Нет - Как правильно установить привязки на уровне модели домена приложения N-Tier MVC3? - PullRequest
7 голосов
/ 20 марта 2012

Я начал использовать Ninject в проекте ASP.NET MVC 3, используя стандартную загрузочную ленту, которая поставляется с пакетом nuget, как показано ниже.

/// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
           // Documentation for setting up Ninject in ASP.NET MVC3 app: 
           // https://github.com/ninject/ninject.web.mvc/wiki/Setting-up-an-MVC3-application

           // Add bindings here. No modules required unless we need to add in further
           // separation of concerns.

           kernel.Bind<ISessionManager>().To<SessionManager>();
           kernel.Bind<ICookieManager>().To<CookieManager>();
           kernel.Bind<ILogManager>().To<LogManager>();
           kernel.Bind<IStringOutput>().To<StringOutput>();
    } 

В моем слое модели домена, есть класс с именем CookieManager.В моем классе CookieManager я использую класс с именем SecureObjectSerializer.

Я хочу использовать внедрение зависимостей, чтобы CookieManager не был тесно связан с SecureObjectSerializer.

Я не хочу, чтобы проект MVC знал о SecureObjectSerializer, настройке привязок и т. Д. Похоже, это слишком далеко для меня. DI 1017 * * 1018Подумайте, что на уровне модели домена, CookieManager должен иметь SecureObjectSerializer, передаваемый в виде DI.

Мои вопросы:

  1. Чтобы регистрация была зарегистрирована в ДоменеСлой модели, я должен создать загрузчик Ninject в слое модели домена?Если так, как я должен был это вызвать.Я бы поставил ловушку и вызвал бы что-то вроде DomainModel.BindModelDependencies(kernel); в проекте MVC.

  2. Когда придет время разрешить новый экземпляр объекта, как будет выглядеть этот код?Это как-то скрыто при использовании загрузчика MVC?

Ответы [ 2 ]

6 голосов
/ 20 марта 2012

Вы должны поместить NinjectModule внутри сборки домена (не веб-сборки), и вы можете указать ninject сканировать вашу сборку домена и искать модуль. Модуль - это просто класс, который наследуется от базового класса NinjectModule и реализует Load (). Таким образом, веб-проекту нужна только ссылка на проект домена. Сканирование должно выглядеть примерно так:

любой из этих двух: (на самом деле есть еще несколько вариантов, но это основные, которые я использую)

var assemblysToScan = "Assembly.*";
var assemblysToScan = new[] { "Assembly.Domain", "Assembly.Web" };

, а затем просто

kernel.Scan(x =>
                {
                    x.From(assemblysToScan)
                    x.AutoLoadModules();
                });

Если вы хотите разрешить объект, просто укажите его в качестве аргумента ctor, и если ninject управляет вашими объектами, он автоматически внедрит тип (на основе настроенных вами привязок).

EDIT:

добавить ссылки на ninjectcommonservicelocator (не могу вспомнить точное имя) & microsoft.practices.servicelocation

в вашем загрузчике добавьте:

using Microsoft.Practices.ServiceLocation;
using CommonServiceLocator.NinjectAdapter;

var locator = new NinjectServiceLocator(kernel);
ServiceLocator.SetLocatorProvider(() => locator);

тогда в вашем классе:

using Microsoft.Practices.ServiceLocation;

class CookieManager : ICookieManager
{
  SecureObjectSerialiser secureObjectSerialiser;

  CookieManager()
  {
    this.secureObjectSerialiser = ServiceLocator.Current.GetInstance<SecureObjectSerialiser>();
  }
}

причина локатора microsoft.practices в том, что ваш код не должен знать, что ninject работает под прикрытием. вместо этого вы используете универсальный сервисный локатор, который можно использовать повторно при смене контейнеров.

лично я бы этого избегал и просто вводил все. но если вы не можете, вы не можете.

3 голосов
/ 03 августа 2012

Принятый ответ относится к методу Scan() из Ninject.Extensions.Conventions.Ninject 3.0 заменил его более мощным интерфейсом для динамического связывания сборок.

    kernel.Bind(x => x
        .FromAssembliesMatching("*")
        .SelectAllClasses()
        .BindDefaultInterface());

Приключение продолжается на вики-расширении .

...