2016-09-03 3 views
-1

Простой пример DI:Как использовать Замок Виндзор набранный завод в этом случае?

public interface INumberToWordConverter 
{ 
    string ConvertNumber(int number); 
} 

public interface IOutputManager 
{ 
    void Write<T>(string who, T what); 
} 

public interface INumberProvider 
{ 
    int GenerateNumber(); 
} 

public class PlayWithDI 
{ 
    private IOutputManager _outputManagerService; 
    private INumberProvider _numberProviderService; 
    private INumberToWordConverter _numberToWordConverterService; 

    private PlayWithDI() { } 
    public PlayWithDI(
     IOutputManager outputManagerService, 
     INumberProvider numberProviderService, 
     INumberToWordConverter numberToWordConverterService) 
    { 
     if (outputManagerService == null) 
      throw new ArgumentNullException(nameof(outputManagerService)); 
     if (numberProviderService == null) 
      throw new ArgumentNullException(nameof(numberProviderService)); 
     if (numberToWordConverterService == null) 
      throw new ArgumentNullException(nameof(numberToWordConverterService)); 

     _outputManagerService = outputManagerService; 
     _numberProviderService = numberProviderService; 
     _numberToWordConverterService = numberToWordConverterService; 
    } 

    public void Execute() 
    { 
     int number = _numberProviderService.GenerateNumber(); 
     string wordOfNumber = _numberToWordConverterService.ConvertNumber(number); 
     _outputManagerService.Write(nameof(PlayWithDI), wordOfNumber); 
    } 

Пример реализации (всего ctors):

// Implements INumberProvider 
public RandomNumberProvider(
     int min, int max, 
     IOutputManager outputManagerService) 
{ 
    ... 
} 

// Implements INumberToWordConverter 
public ItalianNumberToWordConverter(
     IOutputManager outputManagerService) 
{ 
    ... 
} 

// Implements IConsoleManager 
public ConsoleOutputManager() 
{ 
    ... 
} 

Если я знаю, какие min и max дать RandomNumberProvider, я бы просто решить, как это:

public void Install(
     IWindsorContainer container, 
     IConfigurationStore store) 
    { 
     container.Register(
      Component.For<PlayWithDI>()); 

     container.Register(
      Component.For<IOutputManager>() 
      .ImplementedBy<ConsoleOutputManager>()); 

     container.Register(
      Component.For<INumberProvider>() 
      .ImplementedBy<RandomNumberProvider>() 
      .DependsOn(
       Dependency.OnValue("min", 2), 
       Dependency.OnValue("max", 20))); 

     container.Register(
      Component.For<INumberToWordConverter>() 
      .ImplementedBy<ItalianNumberToWordConverter>()); 
    } 

... 
container.Install(new DependenciesConfiguration1()); 
var testDI = container.Resolve<PlayWithDI>(); 
testDI.Execute(); 

Проблема возникает, когда я хочу дать пользовательский p араметры до RandomNumberProvider во время выполнения.

Я взглянул на TypedFactory, но я действительно не понимаю его в этом примере, потому что, если я сначала разрешу фабрику, как мне тогда разрешить PlayWithDi? Должен ли я передать его конструктору INumberProviderFactory вместо INumberProvider?

В этом случае я думал о заводе, как это:

public interface INumberProviderFactory 
{ 
    INumberProvider Create(
     IOutputManager outputManager, 
     int min, int max); 
} 

Когда я затем вызвать Create, как я должен решить outputManager тогда? Я смущен.

ответ

1

Проблема возникает, когда я хочу предоставить пользовательские параметры RandomNumberProvider во время выполнения.

Здесь вы ошибетесь. Injecting runtime data into components during construction is ananti-pattern:

Не вводить данные во время выполнения во время строительства; он вызывает неоднозначность, усложняет корневой состав с дополнительной ответственностью и делает чрезвычайно сложным проверить правильность конфигурации DI. [...] Пусть данные времени выполнения проходят через вызовы методов построенных графиков объектов.

Другими словами, ваш RandomNumberProvider должен принять min и max аргументы является входными параметрами по методу GenerateNumber.

 Смежные вопросы

  • Нет связанных вопросов^_^