2015-08-07 5 views
0

В нашем приложении MVC мы преимущественно используем Ninject для ввода зависимостей в контроллеры. Таким образом, наша продолжительность жизни по умолчанию - InRequestScope(). Теперь мы добавили IHttpModule, который использует общие зависимости в качестве контроллеров (т. Е. UserService). Проблема в том, что HttpModules можно объединить с помощью ASP.NET и IIS и повторно использовать несколько запросов. Поскольку вложенные зависимости установлены в InRequestScope, последующие запросы часто получают ObjectDisposedException при ссылке на вложенные зависимости внутри HttpModule. Как я могу указать InRequestScope() для UserService при введении в контроллер и InScope() при введении в HttpModule.С Ninject, как вы определяете разные сроки жизни в зависимости от привязки?

Вот упрощенная версия нашей регистрации:

public static class NinjectWebCommon 
{ 
    private static readonly Bootstrapper bootstrapper = new Bootstrapper(); 

    public static void Start(){ 
     DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); 
     DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); 
     bootstrapper.Initialize(CreateKernel); 
    } 

    public static void Stop(){ 
     bootstrapper.ShutDown(); 
    } 

    private static IKernel CreateKernel(){ 
     var kernel = new StandardKernel(); 
     kernel.Bind<Func<IKernel>>().ToMethod(ctx =>() => new Bootstrapper().Kernel); 
     kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); 
     kernel.Bind<IHttpModule>().To<CustomModule>(); // needs a UserService 
     kernel.Bind<IUserService>().To<UserService>().InRequestScope(); // injected into controllers and the CustomModule 
     DependencyResolver.SetResolver(new Services.NinjectDependencyResolver(kernel)); 
     return kernel; 
    } 
} 
+0

это может быть частично интересно: http://stackoverflow.com/questions/25167439/ninject-conditional-self-bind-to-change- scope-for-task-scheduler-not-working-p/25174916 # 25174916 – BatteryBackupUnit

ответ

2

Заканчивать .When() на синтаксисе связывания. Вы можете использовать его для указания конкретной области для службы при определенных обстоятельствах. вот пример:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var kernel = new StandardKernel(); 

     var scope1 = new object(); 
     var scope2 = new object(); 

     kernel.Bind<IWidget>().To<WidgetA>().InScope(c => scope1); 
     kernel.Bind<IWidget>().To<WidgetA>().WhenInjectedInto<WidgetController>().InScope(c => scope2); 

     var service = kernel.Get<GeneralWidgetService>(); 
     service.Print(); 

     service = kernel.Get<GeneralWidgetService>(); 
     service.Print(); 

     var controller = kernel.Get<WidgetController>(); 
     controller.Print(); 

     controller = kernel.Get<WidgetController>(); 
     controller.Print(); 

     // when scope2 changes, WidgetController gets a new widget, while WidgetService continues getting the existing widget 
     scope2 = new object(); 

     service = kernel.Get<GeneralWidgetService>(); 
     service.Print(); 

     controller = kernel.Get<WidgetController>(); 
     controller.Print(); 
    } 
} 

public class WidgetController 
{ 
    private readonly IWidget _widget; 

    public WidgetController(IWidget widget) 
    { 
     _widget = widget; 
    } 

    public void Print() 
    { 
     Console.WriteLine("WidgetController ID: " + _widget.ID); 
    } 

} 

public class GeneralWidgetService 
{ 
    private readonly IWidget _widget; 

    public GeneralWidgetService(IWidget widget) 
    { 
     _widget = widget; 
    } 

    public void Print() 
    { 
     Console.WriteLine("GeneralWidgetService ID: " + _widget.ID); 
    } 

} 


public interface IWidget 
{ 
    string ID { get; } 
    string Name { get; } 
} 

public class WidgetA : IWidget 
{ 
    private readonly string _id = Guid.NewGuid().ToString(); 

    public string ID { get { return _id; } } 
    public string Name { get { return "AAAAAAAAAAAAAAAAA"; } } 
} 

Выход:

GeneralWidgetService ID: 09f61af7-c70d-45fe-834a-6cc94e1e3c40
GeneralWidgetService ID: 09f61af7-c70d-45fe-834a-6cc94e1e3c40
WidgetController ID: 2c2bf05f-d251-41be-b9e0-224f02839ead
WidgetController ID: 2c2bf05f-d251-41be-b9e0-224f02839ead
GeneralWidgetService ID: 09f61af7-c70d-45fe-834a-6cc94e1e3c40
WidgetController ID: 519a2930-5b71-4cbb-b84e-a1d712ec5398

+0

Я думаю, что мое замешательство проистекает из того, как регистрируются IHttpModules. Я использовал. Когда() связывает синтаксис с декораторами, но в этом случае будет заглушен. Вот соответствующий код, который прошел мои первоначальные тесты. Я звоню в TestService внутри утилиты TestModule. 'kernel.Bind () .To (); kernel.Bind (). К () .InRequestScope(); kernel.Bind (). () .WhenInjectedInto () .InScope (c => null); ' Спасибо! – DeveloperRob

+0

, если вы используете расширения Ninject.Web, он должен автоматически регистрировать ваши HttpModules для вас и вводить их зависимости. –

+0

Я использую Ninject.Web.Common и Ninject.Web.Mvc. Когда я удаляю 'kernel.Bind () .To ();', модуль не подключается. Я что-то упускаю? – DeveloperRob

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

  • Нет связанных вопросов^_^