Перегрузка конструктора Structuremap - PullRequest
0 голосов
/ 05 августа 2011

У меня есть командный класс, который должен иметь 2 конструктора. Тем не мение, используя Structuremap кажется, что я могу указать только один конструктор использоваться. Я решил проблему на данный момент, подтип конкретных командный класс, который каждая реализация реализует самостоятельно интерфейс и конструктор. Как показывает код ниже. ISelectCommand реализует два отдельных интерфейса для строковый конструктор и конструктор int, просто ради регистрация двух подтипов с использованием структуры карты.

Тем не менее, я считаю это взломом, и мне просто интересно, почему это не так возможно для Structuremap разрешить сигнатуру конструктора тип передается в качестве параметра для конструктора? Тогда я мог бы зарегистрироваться SelectProductCommand в качестве ISelectCommand и создать его как: ObjectFactury.With (10) .Использование> (); . OrObjectFactury.With ( "testproduct") Используйте> ();

public class SelectProductCommand : ISelectCommand<IProduct>,
ICommand, IExecutable
{
   private readonly Func<Product, Boolean> _selector;
   private IEnumerable<IProduct> _resultList;

   public SelectProductCommand(Func<Product, Boolean> selector)
   {
       _selector = selector;
   }

   public IEnumerable<IProduct> Result
   {
       get { return _resultList; }
   }

   public void Execute(GenFormDataContext context)
   {
       _resultList = GetProductRepository().Fetch(context,
_selector);
   }

   private Repository<IProduct, Product> GetProductRepository()
   {
       return ObjectFactory.GetInstance<Repository<IProduct,
Product>>();
   }
}

public class SelectProductIntCommand: SelectProductCommand
{
    public SelectProductIntCommand(Int32 id): base(x =>
 x.ProductId == id) {}
}

public class SelectProductStringCommand: SelectProductCommand
{
    public SelectProductStringCommand(String name): base(x =>
x.ProductName.Contains(name)) {}
}

P.s. Я знаю, как указать structmap, какую карту конструктора использовать, но опять же мой вопрос: есть ли способ заставить structmap выбрать правильный конструктор на основе параметра, переданного в конструктор (т. Е. С использованием обычной перегрузки метода).

Ответы [ 2 ]

1 голос
/ 06 августа 2011

Я думаю, что решил проблему с помощью небольшого служебного класса.Этот класс получает конкретный тип из ObjectFactory и использует этот тип для создания экземпляра в соответствии с параметрами, вставленными в метод фабрики.Теперь на стороне клиента я использую ObjectFactory для создания экземпляра CommandFactory.Реализация CommandFactory находится в другом решении, и поэтому «клиентское решение» остается независимым от «серверного» решения.

public class CommandFactory
{

    public ICommand Create<T>()
    {
        return Create<T>(new object[] {});
    }

    public ICommand Create<T>(object arg1)
    {
        return Create<T>(new[] {arg1});
    }

    public ICommand Create<T>(object arg1, object arg2)
    {
        return Create<T>(new[] {arg1, arg2});
    }

    public ICommand Create<T>(object arg1, object arg2, object arg3)
    {
        return Create<T>(new[] {arg1, arg2, arg3});
    }

    public ICommand Create<T>(object[] arguments)
    {
        return (ICommand)Activator.CreateInstance(GetRegisteredType<T>(), arguments);
    }

    public static Type GetRegisteredType<T>()
    {
        return ObjectFactory.Model.DefaultTypeFor(typeof (T));
    }
}
1 голос
/ 05 августа 2011

Краткий ответ: это сообщение создателя Structuremap .

Длинный ответ касается структуры, которую вы имеете в этом куске кода. На мой взгляд, команда по определению является «классом», который что-то делает с «сущностью», то есть каким-то образом модифицирует класс. Думай CreateNewProductCommand.

Здесь вы используете команды для запросов, если я не ошибаюсь. У вас также есть небольшая проблема с разделением проблем. Размещенная команда определяет, что делать и как это делать, что очень много, и вы получаете такое расположение службы, которое используете в

private Repository<IProduct, Product> GetProductRepository()
{
    return ObjectFactory.GetInstance<Repository<IProduct, Product>>();
}

Способ структурирования команд состоит в том, чтобы использовать CreateProductCommand в качестве контракта данных, то есть он содержит только такие данные, как информация о продукте. Затем у вас есть CreateProductCommandHandler, который реализует IHandles<CreateProductCommand> с помощью одного метода Handle или Execute. Таким образом, вы получаете лучшее разделение забот и тестируемости.

Что касается запрашивающей части, просто используйте свои репозитории непосредственно в вашем контроллере / презентере, или используйте шаблон Query Object

...