Давайте разбить его:
_container.RegisterType<Music>(new InjectionConstructor(
new Album("Non-singleton", "Non-singleton")));
Это регистрируется в контейнере типа Music
без имени (нуль или по умолчанию) и говорит Unity использовать конструктор, который принимает тип Album
. Также всегда нужно передать экземпляр, созданный new Album("Non-singleton", "Non-singleton")
как значение для конструктора Music(Album album)
. Поэтому каждый экземпляр Music
будет иметь тот же альбом, который был введен в него.
_container.RegisterType<Music>(new ContainerControlledLifetimeManager());
Это выполняет регистрацию на основе типа Music
без имени (нуль или по умолчанию). Потому что, нет указателей InjectionMembers, единственным изменением существующей регистрации является добавление менеджера продолжительности жизни. Текущая регистрация обновляется, потому что BuildKey (Тип: Музыка, Имя: null) одинаково для обоих вызовов RegisterType.
unityContainer.RegisterType<Music>(new InjectionConstructor(new Album("Non-singleton", "Non-singleton")));
unityContainer.RegisterType<Music>(new ContainerControlledLifetimeManager());
var music = unityContainer.Resolve<Music>();
var music2 = unityContainer.Resolve<Music>();
bool areEqual = ReferenceEquals(music, music2);
В вышеуказанных isEqual истинно, поэтому возвращается один экземпляр.
Есть ли способ разрешить только одноэлементный тип для двух зарегистрированных объектов в одном контейнере без указания атрибута имени?
типы регистрируются по типу и названию, так что единственный способ иметь несколько регистраций для того же типа, чтобы использовать имя:
Теперь, если вы хотите, чтобы отменить первую регистрацию вы могли бы сделать что, указав новый InjectionConstructor. Это позволит очистить план сборки и установить политику выбора конструктора.
unityContainer.RegisterType<Music>(new InjectionConstructor(
new Album("Non-singleton", "Non-singleton")));
unityContainer.RegisterType<Music>(new ContainerControlledLifetimeManager(),
new InjectionConstructor(new Album("singleton", "singleton")));
Как примечание стороны, вы, как правило, не трудно кода зависимость (в данном случае альбом) внутри типа регистра вызова, если это не было действительно постоянной величиной. Даже тогда вы можете захотеть зарегистрировать постоянный экземпляр как синглтон и позволить контейнеру разрешить его для вас.
Интересный вопрос: как бы вы сбросили политику выбора конструктора после первого вызова RegisterType, чтобы Unity использовала политику выбора конструктора по умолчанию. Вы можете сделать это с помощью специального InjectionMember, который очистит политику выбора конструктора:
unityContainer.RegisterType<Music>(new InjectionConstructor(
new Album("Non-singleton", "Non-singleton")));
unityContainer.RegisterType<Music>(new ContainerControlledLifetimeManager(),
new ClearInjectionConstructor());
public class ClearInjectionConstructor : InjectionMember
{
public override void AddPolicies(Type serviceType,
Type implementationType,
string name,
Microsoft.Practices.ObjectBuilder2.IPolicyList policies)
{
policies.Clear<IConstructorSelectorPolicy>(
new NamedTypeBuildKey(implementationType, name));
}
}