Уважаемые гуру по IoC и по Unity Application Block,
кто как определяет константы именования интерфейсов?
Пример.
public interface Interface1 {}
public interface Interface2 {}
public interface IMyType1 {}
public interface IMyType2 {}
public class MyType1 : Interface1, Interface2, IMyType1
{
public const string UnitName = "MyType1";
...
}
public class MyType2 : Interface1, Interface2, IMyType2
{
public const string UnitName = "MyType2";
...
}
// register interfaces:
unityContainer.RegisterType<Interface1, MyType1>(MyType1.UnitName);
unityContainer.RegisterType<Interface2, MyType1>(MyType1.UnitName);
unityContainer.RegisterType<Interface1, MyType2>(MyYype2.UnitName);
unityContainer.RegisterType<Interface2, MyType2>(MyYype2.UnitName);
// resolving:
var interfaces1 = unityContainer.ResolveAll<Interface1>(); // ok
var interfaces2 = unityContainer.ResolveAll<Interface2>(); // ok
public class SomeWorkForType1
{
SomeWorkForType1(IMyType1 myType) { }
[Dependency(MyType1.UnitName)] // should known about MyType1
public Interface1 Interface1 { get; set; }
[Dependency(MyType1.UnitName)]
public Interface2 Interface2 { get; set; }
}
В результате нужно знать в точке использование конкретного экземпляра интерфейса
MyType1.UnitName, что есть нехорошо для подмены класса(ов) MyType1 & MyType2
для тестирования и иной реализации этих классов.
Куда и как убираете константы типа этих MyType.UnitName ?
Спасибо.
Здравствуйте, Hex66, Вы писали:
H>В результате нужно знать в точке использование конкретного экземпляра интерфейса
H>MyType1.UnitName, что есть нехорошо для подмены класса(ов) MyType1 & MyType2
H>для тестирования и иной реализации этих классов.
Вероятно я что-то недопонял, но зачем одновременно регистрировать все имплементации?
Регистрируйте только то, что нужно в конкретном контейнере — в тесте одна имплементация,
в продакшен — другая. Тогда не придётся с именованием разбираться.
Именование полезно тогда, когда одному типу требуется сопоставить разные имплементации
или экземпляры. Имя в таком случае определяет конкретный контекст сопоставления.
Пример:
interface ITextSource {..}
class DatabaseTextSource : ITextSource {...}
class FileTextSource : ITextSource {...}
class TextFilterer
{
[Dependency("textToFilter")]
public ITextSource Text { get; set; }
[Dependency("linesToExclude")]
public ITextSource ExclusionList { get; set; }
}
container.RegisterType<ITextSource, DatabaseTextSource>("textToFilter");
container.RegisterType<ITextSource, FileTextSource>("linesToExclude");
container.RegisterType<TextFilterer>();
Здравствуйте, bl-blx, Вы писали:
BB>Именование полезно тогда, когда одному типу требуется сопоставить разные имплементации
BB>или экземпляры. Имя в таком случае определяет конкретный контекст сопоставления.
BB>Пример:
BB>BB>interface ITextSource {..}
BB>class DatabaseTextSource : ITextSource {...}
BB>class FileTextSource : ITextSource {...}
BB>class TextFilterer
BB>{
BB> [Dependency("textToFilter")]
BB> public ITextSource Text { get; set; }
BB> [Dependency("linesToExclude")]
BB> public ITextSource ExclusionList { get; set; }
BB>}
BB>container.RegisterType<ITextSource, DatabaseTextSource>("textToFilter");
BB>container.RegisterType<ITextSource, FileTextSource>("linesToExclude");
BB>container.RegisterType<TextFilterer>();
BB>
Вопрос был в том, что куда Вы поместите определение/объявление констант
"textToFilter" & "linesToExclude" ?
Или каждый раз лазить по коду и искать как было поименован тот или иной экземпляр интерфейса?
Заводить такие константы глобальными как-то не уютно.
Имена нужны, так как ResolveAll() работает только для именованных зарегистрированных интерфейсных типов.
Имеется потребность еще в худшем, аля так:
public interface Interface1 { }
public interface Interface2 { }
container.RegisterType<Interface1, MyType>("MyTypeInterface1");
container.RegisterType<Interface2, MyType>("MyTypeInterface2");
public class MyType : Interface1, Interface2
{
// constructor with registry
public MyType(IUnityContainer container)
{
container.RegisterInstance("MyTypeInterface1", this as Interface1);
container.RegisterInstance("MyTypeInterface2", this as Interface2);
}
}
// using:
var interfaces1 = container.ResolveAll<Interface1>();
var interfaces2 = container.ResolveAll<Interface2>();
Опять же где хранить константы "MyTypeInterface1" & "MyTypeInterface2", если в точке
использования MyType невидим?
Здравствуйте, Hex66, Вы писали:
H>Здравствуйте, bl-blx, Вы писали:
BB>>BB>>interface ITextSource {..}
BB>>class DatabaseTextSource : ITextSource {...}
BB>>class FileTextSource : ITextSource {...}
BB>>class TextFilterer
BB>>{
BB>> [Dependency("textToFilter")]
BB>> public ITextSource Text { get; set; }
BB>> [Dependency("linesToExclude")]
BB>> public ITextSource ExclusionList { get; set; }
BB>>}
BB>>container.RegisterType<ITextSource, DatabaseTextSource>("textToFilter");
BB>>container.RegisterType<ITextSource, FileTextSource>("linesToExclude");
BB>>container.RegisterType<TextFilterer>();
BB>>
H>Вопрос был в том, что куда Вы поместите определение/объявление констант
H>"textToFilter" & "linesToExclude" ?
H>Или каждый раз лазить по коду и искать как было поименован тот или иной экземпляр интерфейса?
H>Заводить такие константы глобальными как-то не уютно.
В данном случае скорее в TextFilterer поскольку это его точки инъекции. Согласен, что в случае,
когда есть хотя бы еще один класс куда нужно внедрить то же самое, вопрос остаётся открытым.