2013-04-19 12 views
2

В моем проекте у меня была зависимость контроллера от IRepositoryProvider среди других.Как разрешить впрыск конструктора с несколькими слоями

public class HomeController : BaseController 
{ 
    public HomeController(ISessionWrapper sessionWrapper, 
          IRepositoryProvider repositoryProvider, 
          IApplicationConfiguration applicationConfiguration) 
     : base(sessionWrapper, repositoryProvider, applicationConfiguration) 
    {} 

    ... 

}

IRepositoryProvider и его реализация жить в BLL слое. Другое дело отметить, что IRepositoryProvider также имеет некоторые параметры. Они используются, чтобы определить, какие строки подключения использовать (Environment * 5 возможных подключений).

public RepositoryProvider(string environment, IApplicationConfiguration applicationConfiguration) 
    { 
     _applicationConfiguration = applicationConfiguration; 
     _environment = environment; 
    } 

Все это прекрасно работает с двумя слоями и этой конфигурацией Ninject.

kernel.Bind<IRepositoryProvider>() 
     .To<RepositoryProvider>() 
     .InRequestScope() 
     .WithConstructorArgument("environment",  
           context => context.Kernel.Get<ISessionWrapper>().CurrentEnvironment) 
     .WithConstructorArgument("applicationConfiguration", 
           context => context.Kernel.Get<IApplicationConfiguration>()); 

Моя проблема возникает, когда я представляю сервисный уровень. Вместо того, чтобы полагаться на IRepositoryProvider в моих контроллерах для доступа к данным, я хочу использовать сервисный уровень. В идеале тогда я не хочу ссылаться на слой BLL и только на сервисный уровень.

public class HomeService : IHomeService 
{ 
    public IRepositoryProvider RepositoryProvider { get; private set; } 

    public HomeService(IRepositoryProvider repositoryProvider) 
    { 
     RepositoryProvider = repositoryProvider; 
    } 
    ... 
} 

Итак, мой вопрос заключается в следующем: возможно ли, чтобы я не ссылался на уровень сервиса и BLL из проекта MVC? Или это весь набор массивного запаха кода?

Спасибо.

ОБНОВЛЕНИЕ: Я полагаю, что должен был сказать свои идеальные ссылки. Интернет -> Сервис -> BLL. В настоящий момент Web ссылается на Service и BLL, чтобы Ninject разрешил все.

ОБНОВЛЕНИЕ 2: Это похоже на возможное решение? How to tell Ninject to bind to an implementation it doesn't have a reference to

+0

Вы все равно будете использовать IRepositoryProvider, определенный в BLL, не так ли? Поэтому, я думаю, вам все равно придется ссылаться на него. Но я не вижу, что Ninject имеет к этому отношение. – treze

+0

Я сделал обновление. – merekel

ответ

3

Вот как я обычно архивирую проекты MVC в зависимости от требований.

Уровень презентации> Уровень обслуживания> Уровень бизнес-уровня> Уровень доступа к данным.

Слой презентации содержит: ViewModels, Views, Controllers. (Ссылки на сервисный уровень, Ninject ddl)

Сервисный уровень: WCF. (Ссылки БАЛ и т.д.)

Business Layer: Содержит то, что я называю дирижер и их интерфейсы (Ссылки DAL, домен)

Data Access Layer: Содержит Хранилище и их интерфейсы (Ссылки Доменные)

Домен: Содержит ПОКО объекты

Ядро: Где я на самом деле установить и настроить Ninject (Ссылки на BAL, DAL и т.д.)

чтобы добавить Ninject к другому проекту, кроме Presentati на уровне:

Добавьте следующий Global.Asasx.cs:

DependencyResolver.SetResolver(new NinjectDependencyResolver()); 

Затем создайте новый проект sucche в качестве ядра.Установите Ninject там и добавить следующий класс:

Вам нужно будет ссылаться на DLL Ninject из представительского уровня

public class NinjectDependencyResolver : IDependencyResolver { 
    private IKernel kernel; 

    public NinjectDependencyResolver() 
    { 
     kernel = new StandardKernel(); 
     AddBindings(); 
    } 

    public object GetService(Type serviceType) 
    { 
     return kernel.TryGet(serviceType); 
    } 

    public IEnumerable<object> GetServices(Type serviceType) 
    { 
     return kernel.GetAll(serviceType); 
    } 

    public IBindingToSyntax<T> Bind<T>() 
    { 
     return kernel.Bind<T>(); 
    } 

    public IKernel Kernel 
    { 
     get { return kernel; } 
    } 

    private void AddBindings() 
    { 
     //Add your Bindings here 
    } 

} 
+0

Реализация ISessionWrapper используется в разных местах на некоторых контроллерах. IApplicationConfiguration Я предположил, что можно удалить, так как он используется только в 1 или 2 раза для контроллеров, я не вижу, как все это связано с тем, что я просил. – merekel

+0

Значит, он используется как в контроллере (-ах), так и в хранилище (-ях)? – Flavia

+0

Какие?ISessionWrapper используется только на веб-уровне, но он содержит текущую выбранную среду, которая необходима, чтобы знать, какие подключения использовать. IApplicationConfiguration используется для извлечения правильных строк подключения, а также для некоторых других параметров web.config (таких как допустимые группы AD, доступные среды и т. Д.). – merekel

2

IRepositoryProvider и его реализация жить в BLL слое ... это возможно для меня, чтобы не ссылаться как на службу и BLL слои из проекта MVC

с этими двумя утверждением твоей ответ нЕТ, вы не можете «не» ссылаться на эти слои. Наилучший подход к минимизации ссылок - отделить ваши интерфейсы от реализаций. Вы можете иметь, например, следующее: Layer

Домен, содержит свой POCO и интерфейс

  • продукт (класс образец)
  • IRepository (интерфейс)

Сервисный уровень, содержит реализацию ваших интерфейсов

  • Имеются ссылки на слой Domain
  • Редукторы IRepository (например, ProductRepository : IRepository)

Dependency Injection Layer

  • Знает обоих Domain и Service слоев

MVC проекта

  • Обратитесь к слою Domain, чтобы узнать о подписях POCOs и репозиториях
  • Имеете ссылку на слой DI, но не знаете, как именно это делается . Таким образом, вы можете поменять структуру DI позже, и все будет работать.

Вы можете расширить этот слой по своему усмотрению. Вы можете вставить слой BLL между слоями Domain и Service, и вам не нужно ссылаться нигде.

+0

Вы имели в виду, что MVC ссылается только на уровень сервиса вместо домена? Из того, что я вижу, Ninject все еще должен знать оба типа (интерфейс и бетон). Я также внесла изменения в свой вопрос об использовании модулей и Ninject. – merekel

+0

Inject должен знать, что это правильно, и это потому, что это задача Ninject знать об этом. Он будет создавать объект, а не проект MVC. Поэтому Ninject должен знать все, и MVC просто должен знать о Домене (и подписи/intefaces). –

+0

Моя точка зрения заключалась в том, что если Ninject должен знать оба, то необходимо будет указать оба уровня. – merekel

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