2011-08-05 2 views
0

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

Однако, я считаю, что это взломать, и я просто задаюсь вопросом, почему это не так? Возможно, для structmap разрешить подпись конструктора по типу , переданному в качестве параметра для конструктора? Тогда я мог бы зарегистрировать SelectProductCommand как ISelectCommand и создать экземпляр: ObjectFactury.With (10) .Use>(); 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. Я знаю, как сообщить структуре, какую конструкторную карту использовать, но опять мой вопрос в том, есть ли способ, чтобы структура структуры выбирала правильный конструктор на основе параметра, переданного конструктору (т. Е. С использованием регулярной перегрузки метода).

ответ

1

Я думаю, что я решил проблему с помощью небольшой утилиты класса. Этот класс получает конкретный тип от 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

Короткий ответ this post by the creator of Structuremap.

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

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

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

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

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

+0

Вот некоторые ссылки, чтобы вы собираетесь на команд/обработчиков: http://lostechies.com/jimmybogard/2010/01/07/advanced-structuremap-custom-registration-conventions-for-partially- закрытые типы/ http://lostechies.com/derickbailey/2008/11/20/ptom-command-and-conquer-your-ui-coupling-problems/ – Henning

+0

Прошу прощения, но это не тот ответ, который я искал для. Я знаю сообщение, которое вы упомянули Джереми Миллером.Но, как я уже упоминал, это касается прежде всего указания конкретного конструктора. Что касается ваших комментариев по шаблону команды, спасибо, я посмотрю на это. Однако вы должны понимать, что класс команд (возможно, именование не подходит) - это всего лишь оболочка метода select для извлечения продукта из репозитория. У меня также есть команды вставки, удаления и обновления. Цель этой настройки заключается в том, что я могу добавить их в список команд, которые передаются диспетчеру транзакций. – halcwb

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