UnityContainer ResolveAll() naming interfaces
От: Hex66 Россия  
Дата: 13.05.13 12:53
Оценка:
Уважаемые гуру по 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 ?

Спасибо.
Re: UnityContainer ResolveAll() naming interfaces
От: bl-blx Россия http://yegodm.blogspot.com
Дата: 13.05.13 13:43
Оценка:
Здравствуйте, 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>();
El pueblo unido jamás será vencido.
Re[2]: UnityContainer ResolveAll() naming interfaces
От: Hex66 Россия  
Дата: 13.05.13 14:30
Оценка:
Здравствуйте, 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 невидим?
Re[3]: UnityContainer ResolveAll() naming interfaces
От: bl-blx Россия http://yegodm.blogspot.com
Дата: 13.05.13 15:41
Оценка:
Здравствуйте, 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 поскольку это его точки инъекции. Согласен, что в случае,
когда есть хотя бы еще один класс куда нужно внедрить то же самое, вопрос остаётся открытым.
El pueblo unido jamás será vencido.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.