2015-04-27 3 views
0

У меня есть требование создать метод синхронизации. 1) На входе требуется объект SyncRequest.Список процессов по типу

class SyncRequest{ 
    public List<SyncObj> Objects{get;set;} 
} 
class SyncObj{ 
    public Type Type{get;set;} 
    public object Object{get;set;} 
} 

2) На основании типа каждого объекта нужно использовать другую службу для продолжения и другого хранилища для сохранения данных.

I.e. если я получил 3 объекта с типами User, User, Task. Я буду группировать их по типу, а затем продолжить работу с UserService и TaskService.
Я пытаюсь архитектор web.api с архитектурой лука. Где DataAccess, Core, Services отделены друг от друга. И я хочу избежать swich или if's, в моем коде.

Все идеи, которые я придумал, были уродливыми. Например, Dicitionary<Type, Service> и ручное литье.

Я чувствую, что у Ninject может быть действительно удачный ответ на мою проблему, с некоторыми фабричными функциями, но я не могу придумать это.

Может ли кто-нибудь описать, как этот шаблон должен работать. Или как этот шаблон вызывает, где читать.

+0

Не уверен, что я правильно понял, но [Handler-Patern] (http://simon-says-architecture.com/2011/09/13/the-handler-pattern/), кажется, подходит хорошо. – john

+0

выполняют различные сервисы ('UserService',' TaskService') совместно используют интерфейс? – BatteryBackupUnit

+0

[Эта статья] (https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91) описывает шаблон обработчика, который описывает @john более подробно. – Steven

ответ

1

Поскольку у вас есть Type так или иначе, вам придется использовать Reflection. Другой вопрос - как вы обращаетесь к контейнеру DI (ядро ninject).

Вы можете сделать что-то вроде этого:

public interface IHandler<T> 
{ 
    void Handle(T obj); 
} 

public void UserService : IHandler<User> {...} 

Bind<IHandler<User>>().To<UserService>(); 

который вы бы затем использовать так:

foreach(var syncObj in syncRequest.Objects) 
{ 
    Type handlerType = typeof(IHandler<>).MakeGeneric(syncObj.Type); 
    MethodInfo handleMethod = handlerType.GetMethod("Handle"); 

    object handler = kernel.Get(handlerType); 

    handleMethod.Invoke(handler, new object[] { syncObj.Object }); 
} 

Как видите, вы будете иметь доступ к контейнеру как-то для создания определенного типа. Вы можете ввести его как IResolutionRoot. Чтобы придерживаться лукового слоя, вам нужно будет переместить код, который использует ядро, в корень композиции и дать ему интерфейс ... Поскольку вы, похоже, знаете о луковом слое, я больше не буду вдаваться в подробности :)

+0

обработчик объекта = kernel.Get (обработчик); Вы имели в виду .Get (handlerType)? –

+0

Да, спасибо, исправим. – BatteryBackupUnit

+0

btw. я просто закодировал его простым текстом, не компилировал его, чтобы могли быть другие незначительные ошибки. – BatteryBackupUnit

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