在 StructureMap 中注册复合模式
Register composite pattern in StructureMap
在我的项目中,我使用复合模式,我想使用 StructureMap 注册和解析此层次结构。
代码看起来像这样
interface IFoo
{
void Do();
}
class Foo1 : IFoo
{
public void Do()
{
Console.WriteLine("Foo1");
}
}
class Foo2 : IFoo
{
public void Do()
{
Console.WriteLine("Foo2");
}
}
class CompositeFoo : IFoo
{
private readonly IEnumerable<IFoo> foos;
public CompositeFoo(IEnumerable<IFoo> foos)
{
this.foos = foos;
}
public void Do()
{
foreach (var foo in this.foos)
{
foo.Do();
}
}
}
class Bootstrapper
{
public static void Run()
{
var container = new Container(c =>
{
c.For<IFoo>().Add<Foo1>();
c.For<IFoo>().Add<Foo2>();
c.For<IFoo>().Use<CompositeFoo>();
});
// throws exception
var result = container.GetInstance<IFoo>();
result.Do();
}
}
指定代码抛出此异常
Bi-directional dependency relationship detected!
Check the StructureMap stacktrace below:
1.) Instance of IFoo (CompositeFoo)
2.) All registered children for IEnumerable<IFoo>
3.) Instance of IEnumerable<IFoo>
4.) new CompositeFoo(*Default of IEnumerable<IFoo>*)
5.) CompositeFoo
6.) Instance of IFoo (CompositeFoo)
7.) Container.GetInstance<IFoo>()
我在官方文档或互联网上的任何地方都找不到与此相关的任何内容。如果不手动指定所有可能的依赖项,这是完全可能的吗?
在我看来,您有两种选择:
将 CompositeFoo
注册为 CompositeFoo
而不是 IFoo
。然后请求 CompositeFoo
.
的实例
cfg.For<IFoo>().Add<Foo1>();
cfg.For<IFoo>().Add<Foo2>();
cfg.ForConcreteType<CompositeFoo>();
...
var result = container.GetInstance<CompositeFoo>();
为组合定义一个新接口。
interface ICompositeFoo : IFoo {}
class CompositeFoo : ICompositeFoo
...
cfg.For<IFoo>().Add<Foo1>();
cfg.For<IFoo>().Add<Foo2>();
cfg.For<ICompositeFoo>().Use<CompositeFoo>();
...
var foo = container.GetInstance<ICompositeFoo>();
在尝试使用策略或工厂 类 完成此操作后,我解雇了 StructureMap 以支持 Grace。在那里我可以使用以下代码轻松实例化复合对象
var container = new DependencyInjectionContainer();
container.Configure(c =>
{
c.Export<Foo1>().As<IFoo>();
c.Export<Foo2>().As<IFoo>();
c.Export<CompositeFoo>().As<IFoo>();
});
var foo = container.Locate<IFoo>();
foo.Do();
结果如预期:
foo1
foo2
对我来说,StructureMap 的问题是它们不支持任何动态指定对象依赖关系的方式。如果我手动编写所有应该注入或解析所有实例(包括复合对象),我可以让它工作。我可能可以使用带有注入容器的策略并以这种方式指定依赖项,以某种方式使其成为可能,但在我看来这太老套了。
在我的项目中,我使用复合模式,我想使用 StructureMap 注册和解析此层次结构。 代码看起来像这样
interface IFoo
{
void Do();
}
class Foo1 : IFoo
{
public void Do()
{
Console.WriteLine("Foo1");
}
}
class Foo2 : IFoo
{
public void Do()
{
Console.WriteLine("Foo2");
}
}
class CompositeFoo : IFoo
{
private readonly IEnumerable<IFoo> foos;
public CompositeFoo(IEnumerable<IFoo> foos)
{
this.foos = foos;
}
public void Do()
{
foreach (var foo in this.foos)
{
foo.Do();
}
}
}
class Bootstrapper
{
public static void Run()
{
var container = new Container(c =>
{
c.For<IFoo>().Add<Foo1>();
c.For<IFoo>().Add<Foo2>();
c.For<IFoo>().Use<CompositeFoo>();
});
// throws exception
var result = container.GetInstance<IFoo>();
result.Do();
}
}
指定代码抛出此异常
Bi-directional dependency relationship detected!
Check the StructureMap stacktrace below:
1.) Instance of IFoo (CompositeFoo)
2.) All registered children for IEnumerable<IFoo>
3.) Instance of IEnumerable<IFoo>
4.) new CompositeFoo(*Default of IEnumerable<IFoo>*)
5.) CompositeFoo
6.) Instance of IFoo (CompositeFoo)
7.) Container.GetInstance<IFoo>()
我在官方文档或互联网上的任何地方都找不到与此相关的任何内容。如果不手动指定所有可能的依赖项,这是完全可能的吗?
在我看来,您有两种选择:
将
的实例CompositeFoo
注册为CompositeFoo
而不是IFoo
。然后请求CompositeFoo
.cfg.For<IFoo>().Add<Foo1>(); cfg.For<IFoo>().Add<Foo2>(); cfg.ForConcreteType<CompositeFoo>(); ... var result = container.GetInstance<CompositeFoo>();
为组合定义一个新接口。
interface ICompositeFoo : IFoo {} class CompositeFoo : ICompositeFoo ... cfg.For<IFoo>().Add<Foo1>(); cfg.For<IFoo>().Add<Foo2>(); cfg.For<ICompositeFoo>().Use<CompositeFoo>(); ... var foo = container.GetInstance<ICompositeFoo>();
在尝试使用策略或工厂 类 完成此操作后,我解雇了 StructureMap 以支持 Grace。在那里我可以使用以下代码轻松实例化复合对象
var container = new DependencyInjectionContainer();
container.Configure(c =>
{
c.Export<Foo1>().As<IFoo>();
c.Export<Foo2>().As<IFoo>();
c.Export<CompositeFoo>().As<IFoo>();
});
var foo = container.Locate<IFoo>();
foo.Do();
结果如预期:
foo1
foo2
对我来说,StructureMap 的问题是它们不支持任何动态指定对象依赖关系的方式。如果我手动编写所有应该注入或解析所有实例(包括复合对象),我可以让它工作。我可能可以使用带有注入容器的策略并以这种方式指定依赖项,以某种方式使其成为可能,但在我看来这太老套了。