С Ninject, как вы определяете различные времена жизни в зависимости от привязки?

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

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

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;
    }
}

1 ответ

Решение

Проверять, выписываться .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: 2c2bf05f-d251-41be-b9e0-224f02839ead
Идентификатор WidgetController: 2c2bf05f-d251-41be-b9e0-224f02839ead
GeneralWidgetService ID: 09f61af7-c70d-45fe-834a-6cc94e1e3c40
WidgetController ID: 519a2930-5b71-4cbb-b84e-a1d712ec5398

Другие вопросы по тегам