У меня есть сервисный уровень, который извлекает DTO из хранилища.В зависимости от свойства в этом DTO мне нужно использовать одну из двух стратегий для выполнения расчетов в DTO.Я создал фабрику для возврата соответствующей стратегии, и я использую DI-контейнер ( Munq ) для создания экземпляра объекта.
public class CalculationFactory
{
private readonly IDependencyResolver _resolver;
public CalculationFactory(IDependencyResolver resolver)
{
ThrowIfNullArgument(resolver, "resolver", typeof(IDependencyResolver));
_resolver = resolver;
}
public static ICalculation CreateCalculator(int serviceType)
{
switch (serviceType)
{
case 1: return _resolver.Resolve<ICalculation>("Type1");
case 2: return _resolver.Resolve<ICalculation>("Type2");
default: return _resolver.Resolve<ICalculation>("InvalidType");
}
}
}
Для этого необходимо передать преобразователь зависимостейкогда я создаю экземпляр фабрики, чтобы ее можно было использовать для разрешения / создания соответствующих вычислений.Это правильный подход?Если я хочу добавить новый тип расчета, мне нужно обновить заводской метод CreateCalculator и зарегистрировать новый тип.
Update (long) Я не получаю поддержкуБоюсь предложений.Я вернулся к своей копии DI Марка в .Net и, в частности, к главе 6 о рефакторинге.Итак, у меня есть класс MeterReadings , и мне нужно рассчитать заряд, используя один из двух расчетов на основе значения времени выполнения.Я добавляю абстрактную фабрику в смесь, но на моей бетонной фабрике мне все еще нужно новый до соответствующего расчета.Я чувствую, что здесь не хватает смысла:
public enum ServiceType
{
Actuals = 1, CopyBlock,
}
public interface IChargeCalculator
{
decimal CalculateCharge();
}
public interface IChargeCalculatorFactory
{
IChargeCalculator CreateChargeCalculator(ServiceType serviceType);
}
public class MeterReading
{
private readonly IChargeCalculatorFactory chargeCalculatorFactory;
public MeterReading(IChargeCalculatorFactory chargeCalculatorFactory)
{
if (chargeCalculatorFactory == null)
throw new ArgumentNullException("chargeCalculatorFactory");
this.chargeCalculatorFactory = chargeCalculatorFactory;
}
}
public class ConcreteChargeCalculatorFactory : IChargeCalculatorFactory
{
public IChargeCalculator CreateChargeCalculator(ServiceType serviceType)
{
switch (serviceType)
{
case ServiceType.Actuals : return new ActualsChargeCalculator();
default: return new CopyBlockChargeCalculator();
}
}
}
Но в моем контейнере я могу зарегистрировать различные калькуляторы, и если я передаю в контейнер бетонный завод, я получаю что-то вроде следующего (не проверено) что откровенно выглядит довольно разумно для меня.Любые отзывы / разъяснения приветствуются.
Container.Register<IChargeCalculator>("Actuals",
c => new ActualsChargeCalculator());
Container.Register<IChargeCalculator>("CopyBlock",
c => new CopyBlockChargeCalculator());
...
public enum ServiceType
{
Actuals = 1, CopyBlock,
}
public interface IChargeCalculator
{
decimal CalculateCharge();
}
public class MeterReading
{
private readonly IDependencyResolver chargeCalculatorFactory;
private ServiceType serviceType;
public MeterReading(IDependencyResolver chargeCalculatorFactory)
{
if (chargeCalculatorFactory == null)
throw new ArgumentNullException("chargeCalculatorFactory");
this.chargeCalculatorFactory = chargeCalculatorFactory;
}
public decimal Charge
{
get
{
return chargeCalculatorFactory.Resolve<IChargeCalculator>(serviceType.ToString());
}
}
}