所以我有:
应用程序A:需要B类(不同的程序集)
B类:需要C级(同样,不同的装配)
C类:使用容器来解析各种对象,但是容器的生命周期(以及它解析的对象)应该由组合根控制。
我想我理解这在大多数情况下是如何工作的,但是在C类中,我需要根据传入的对象的属性来解决。
我认为我要问的是,容器是否已成为一种依赖关系,因此,如何最好地将它放在需要的地方(不确定我是否真的希望将它传递给一堆施工人员 - 物业注入是否可行?)
我相信这个来源尽可能干净简洁:
namespace InjectionTest
{
using System;
using Microsoft.Practices.Unity;
public class ApplicationA
{
static void Main(string[] args)
{
using (IUnityContainer container = new UnityContainer())
{
// Normally I'd use this, but for clarity in the example, I'm doing it in code.
//container.LoadConfiguration();
container.RegisterType<IClassB, ClassB>();
container.RegisterType<IClassC, ClassC>();
container.RegisterType<IFooBuilder, FrobBuilder>("frob");
container.RegisterType<IFooBuilder, WidgetBuilder>("widget");
IClassB machine = container.Resolve<IClassB>();
InitialObject bar = new InitialObject() { Name = "widget" };
machine.doSomethingWithBar(bar);
bar = new InitialObject() { Name = "frob" };
machine.doSomethingWithBar(bar);
}
}
}
public class ClassB : IClassB
{
IClassC classC { get; private set; }
public ClassB(IClassC classc)
{
this.classC = classc;
}
public void doSomethingWithBar(InitialObject bar)
{
var foo = this.classC.BuildMyFoo(bar);
/*
* Do something else with foo & bar
* */
}
}
public interface IClassB
{
void doSomethingWithBar(InitialObject bar);
}
public class ClassC : IClassC
{
public ResultObject BuildMyFoo(InitialObject bar)
{
IFooBuilder builder = null;
//How best do I get my container here?
//IFooBuilder builder = container.Resolve<IFooBuilder>(bar.Name);
return builder.build(bar);
}
}
public interface IClassC
{
ResultObject BuildMyFoo(InitialObject bar);
}
public class InitialObject
{
public string Name { get; set; }
}
public class ResultObject
{
public string SomeOtherData { get; set; }
}
public interface IFooBuilder
{
ResultObject build(InitialObject bar);
}
public class FrobBuilder : IFooBuilder
{
public ResultObject build(InitialObject bar)
{
throw new NotImplementedException();
}
}
public class WidgetBuilder : IFooBuilder
{
public ResultObject build(InitialObject bar)
{
throw new NotImplementedException();
}
}
}
编辑:这就是我使用属性注入的方式:
我改变了ClassC:
public class ClassC : IClassC
{
[Dependency]
public IUnityContainer Container { get; set; }
public ResultObject BuildMyFoo(InitialObject bar)
{
IFooBuilder builder = null;
//How best do I get my container here?
builder = Container.Resolve<IFooBuilder>(bar.Name);
return builder.build(bar);
}
}
并在ApplicationA中更新了我的Main方法:
public void Main()
{
using (IUnityContainer container = new UnityContainer())
{
// Normally I'd use this, but for clarity in the example, I'm doing it in code.
//container.LoadConfiguration();
container.RegisterType<IClassB, ClassB>();
container.RegisterType<IClassC, ClassC>();
container.RegisterType<IFooBuilder, FrobBuilder>("frob");
container.RegisterType<IFooBuilder, WidgetBuilder>("widget");
using (IUnityContainer child = container.CreateChildContainer())
{
container.RegisterInstance<IUnityContainer>(child);
IClassB machine = container.Resolve<IClassB>();
InitialObject bar = new InitialObject() { Name = "widget" };
machine.doSomethingWithBar(bar);
bar = new InitialObject() { Name = "frob" };
machine.doSomethingWithBar(bar);
}
}
}
答案 0 :(得分:8)
你绝对不想传递容器。您应该查看Unity工厂支持,它将在这种情况下工作。像这样:
container.RegisterType<IFooBuilder, FrobBuilder>("Frob")
.RegisterType<IFooBuilder, WidgetBuilder>("Widget")
.RegisterType<Func<string, IFooBuilder>>(new InjectionFactory(c => new Func<string, IFooBuilder>(barName => c.Resolve<IFooBuilder>(barName))))
然后ClassC的构造函数参数为Func:
public class ClassC : IClassC
{
private readonly Func<string, IFooBuilder> _builderFactory;
public ClassC(Func<string, IFooBuilder> builderFactory)
{
_builderFactory = builderFactory;
}
public ResultObject BuildMyFoo(InitialObject bar)
{
IFooBuilder builder = _builderFactory(bar.Name);
return builder.build(bar);
}
}