Так у меня есть:Должен ли я передавать Контейнер Unity в мои зависимости?
Применение 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();
}
}
}
Edit: Это, как я сделал это работать с впрыском собственности:
я изменил 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:
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);
}
}
}
OK - Так что я закончил этот пример и получил это работает. инъекция свойств выглядит как путь, мне просто нужно зарегистрировать дочерний контейнер в качестве экземпляра, который я хочу использовать (регистрация результатов верхнего уровня в результате переполнения стека). Я все равно буду благодарен за любые ответы, так как я новичок в этом деле. –
Хорошо, теперь я вижу здесь http://stackoverflow.com/questions/827756/can-a-unity-container-pass-a-reference-of-itself-as-a-constructor-parameter, что я даже не должны создать ребенка - я просто должен отметить свойство как зависимость, и единство автоматически вводит текущий контейнер. Я думаю, что это еще чище. –
Связанный: http://stackoverflow.com/questions/2386487/is-it-better-to-create-a-singleton-to-access-unity-container-or-pass-it-through-t –