Unity Application Block, унаследованная инъекция
-
20-08-2019 - |
Вопрос
У меня проблема с использованием блока приложений Unity, я создал базовый класс под названием Composition. Р>
Каждая Композиция содержит IUnityContainer, когда я создаю объект верхнего уровня UniversalComposition, я хочу инициализировать его с помощью UnityContainer. Р>
Любой объект, который создается из UniversalComposition. Я хочу добавить в него дочерний объект IUnityContainer, используя метод IUnityContainer.CreateChildContainer.
class Program
{
static void Main(string[] args)
{
UniversalComposition universe = new UniversalComposition();
}
}
public class UniversalComposition : Composition
{
// Everything that gets resolved in this container should contain a child container created by the this container
public UniversalComposition()
{
this.Container.RegisterType<IService, Service>();
}
protected override IUnityContainer CreateContainer()
{
return new UnityContainer();
}
}
public abstract class Composition
{
protected IUnityContainer Container {get; private set;}
public Composition()
{
this.Container = this.CreateContainer();
}
public TInstance Resolve<TInstance>()
{
return this.Container.Resolve<TInstance>();
}
protected abstract IUnityContainer CreateContainer();
}
public class Service : Composition, IService
{
public Service(/* I want to inject a child Unity Container in here container.CreateChildContainer() */)
{
}
}
public interface IService { }
Решение
Я не думаю, что это будет работать с помощью внедрения, так как он реализован в родительском контейнере, поскольку родительский контейнер не существует, пока не будет создан экземпляр дочернего объекта. Таким образом, у вас нет возможности создать дочерний контейнер для внедрения. Лучшим способом было бы внедрить родительский контейнер через параметризованный конструктор в базовый класс, а затем внедрить оба в дочерний класс. Конструктор по умолчанию может вызвать параметризованный конструктор с нулевым значением, а параметризованный конструктор может обнаружить это и создать контейнер, если он не указан. Приведенный ниже пример упрощен для ясности.
public abstract class BaseClass
{
public IUnityContainer Container { get; protected set; }
public BaseClass() : BaseClass(null) {}
public BaseClass( IUnityContainer container )
{
this.container = container ?? this.CreateContainer();
}
public abstract IUnityContainer CreateContainer();
}
public class DerivedClass : BaseClass
{
public IUnityContainer ChildContainer { get; private set; }
public DerivedClass() : DerivedClass(null,null) {}
public DerivedClass( IUnityContainer parent, IUnityContainer child )
: BaseClass( parent )
{
this.ChildContainer = child ?? this.CreateChildContainer();
}
public IUnityContainer CreateContainer()
{
return new UnityContainer();
}
public IUnityContainer CreateChildContainer()
{
return this.Container.CreateChildContainer();
}
}