2013-10-09 6 views
1

Я использую Ninject в проекте C# 4.5 в качестве контейнера IoC. Я пытаюсь использовать Ninject для ввода абстрактного шаблона фабрики, который отлично работает в MVC, но не в Web Api.Ninject в MVC и WebAPI для создания абстрактной фабрики

Я установлены следующие компоненты:

Ninject 3.0.1.10 
Ninject.Extensions.WCF 3.0.0.5 
Ninject.MVC3 3.0.0.6 
Ninject.Web.Common 3.0.0.7 
SignalR.Ninject 

Моя фабрика классов выглядеть следующим образом:

public interface IBusinessEngineFactory 
{ 
    T GetBusinessEngine<T>() where T : IBusinessEngine; 
} 

public interface IBusinessEngine 
{ 
} 

public class BusinessEngineFactory : IBusinessEngineFactory 
{ 

    private IKernel Kernel { get; set; } 

    public BusinessEngineFactory(IKernel kernel) 
    { 
     Kernel = kernel; 
    } 

    T IBusinessEngineFactory.GetBusinessEngine<T>() 
    { 
     return Kernel.Get<T>(); 
    } 
} 

У меня есть стандартный NinjectWebCommon:

общественный статический класс NinjectWebCommon { частных статических readonly Bootstrapper bootstrapper = new Bootstrapper();

/// <summary> 
    /// Starts the application 
    /// </summary> 
    public static void Start() 
    { 
     DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); 
     DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); 
     bootstrapper.Initialize(CreateKernel); 
    } 

    /// <summary> 
    /// Stops the application. 
    /// </summary> 
    public static void Stop() 
    { 
     bootstrapper.ShutDown(); 
    } 

    /// <summary> 
    /// Creates the kernel that will manage your application. 
    /// </summary> 
    /// <returns>The created kernel.</returns> 
    private static IKernel CreateKernel() 
    { 
     var kernel = new StandardKernel(); 
     kernel.Bind<Func<IKernel>>().ToMethod(ctx =>() => new Bootstrapper().Kernel); 
     kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); 

     RegisterServices(kernel); 
     // Install our Ninject-based IDependencyResolver into the Web API config 
     GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel); 
     return kernel; 
    } 

    /// <summary> 
    /// Load your modules or register your services here! 
    /// </summary> 
    /// <param name="kernel">The kernel.</param> 
    private static void RegisterServices(IKernel kernel) 
    { 
     kernel.Bind<IUserIdentity>().To<UserIdentity>(); 
     kernel.Bind<IUnitOfWork>().To<UnitOfWork>(); 
     kernel.Bind<IAlarmEngine>().To<AlarmEngine>(); 
     kernel.Bind<IBusinessEngineFactory>().To<BusinessEngineFactory>(); 
    }   
} 

Это устанавливается в контроллере, таким образом

public class UserController : BaseController 
{ 

    public UserController(IBusinessEngineFactory businessEngineFactory, IUnitOfWork unitOfWork, UserIdentity userIdentity) 
     : base(businessEngineFactory, unitOfWork, userIdentity) 
    { 

    } 

... 

    public ActionResult Edit(int id = 0) 
    { 
... 
     var x = BusinessEngineFactory.GetBusinessEngine<IAlarmEngine>(); 
     x.ProcessAlarmEventUpdate("test"); 

     return View(x); 
    } 
} 

, который работает отлично. Где у меня есть проблемы идентичен код в WebAPIController:

public class AlarmWebApiController : ApiController 
{ 

    public IBusinessEngineFactory BusinessEngineFactory { get; set; } 

    public IUnitOfWork UnitOfWork {get; set;} 

    public IUserIdentity UserIdentity { get; set; } 

    public AlarmWebApiController(IBusinessEngineFactory businessEngineFactory, IUnitOfWork unitOfWork, IUserIdentity userIdentity) 
    { 
     if (businessEngineFactory == null) throw new NullReferenceException("businessEngineFactory"); 
     BusinessEngineFactory = businessEngineFactory; 
     if (unitOfWork == null) throw new NullReferenceException("unitOfWork"); 
     UnitOfWork = unitOfWork; 
     if (userIdentity == null) throw new NullReferenceException("userIdentity"); 
     UserIdentity = userIdentity; 
    } 

} 

Когда я запускаю это процессы контроллера MVC отлично, но функция Web API не делает и я получаю сообщение неясного об ошибке, которое происходит перед любым кодом в конструкторе из webapi.

«Ошибка при загрузке Ninject компонент ICACHE

Ни один из компонентов не был зарегистрирован в компоненте контейнере ядра»

Я думаю, что проблема заключается в том, что MVC имеет знание ядра, но потому, что WebAPI использует это:

GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel); 

поэтому он не знает ядро. Код для создания бизнес-механизма существует в другом проекте для основного MVC, веб-API и создания ninject, и я бы предпочел не привязывать зависимость к System.Web.Http (для объекта GlobalConfiguration.Configuration.DependencyResolver), если я могу Помоги. Есть ли способ заставить его работать как с MVC, так и с WebAPI?

Заранее спасибо

ответ

0

Я исправил эту проблему, так что IoC бы придать абстрактную фабрику и возвращает правильную конкретную реализацию как в MVC и WebAPI. В конце концов, мое решение было следующие пакеты:

<package id="Ninject" version="3.0.1.10" targetFramework="net40" /> 
<package id="Ninject.Extensions.Wcf" version="3.0.0.5" targetFramework="net40" /> 
<package id="Ninject.MVC3" version="3.0.0.6" targetFramework="net40" /> 
<package id="Ninject.Web.Common" version="3.0.0.7" targetFramework="net40" /> 
<package id="Ninject.Web.WebApi-RC" version="3.0.0.22" targetFramework="net45" /> 

Завод бизнес двигатель был модифицирован для использования в следующем:

public class BusinessEngineFactory : IBusinessEngineFactory 
{ 

    private IResolutionRoot resolutionRoot { get; set; } 

    public BusinessEngineFactory(IResolutionRoot resolutionRoot) 
    { 
     this.resolutionRoot = resolutionRoot; 
    } 

    T IBusinessEngineFactory.GetBusinessEngine<T>() 
    { 
     return this.resolutionRoot.Get<T>(); 
    } 
} 

Я пытался использовать пакет Ninject.Web.WebApi, который не сделал работа и Ninject.Web.WeApi.Updated, которые остановили мое решение от запуска с сообщением об ошибке «исключение было вызвано целью вызова» при запуске приложения. Возвращаясь к старой версии, было решение, так что теперь все работает нормально. Я даже проверил, что он работал в WCF!