Configuring Ninject

亡梦爱人 提交于 2019-12-24 00:59:47

问题


Following a discussion with Remo Gloor (main dev) about our Ninject configuration, .NET memory profiling / risks for leaks / Ninject / Direct delegate roots, I'd like to get some clarity on configuring it properly for an ASP.NET webforms application.

We have a requirement currently where we are doing the following:

Bind<ISearchService>()
    .ToMethod(ctx => new BaseSearchService(ctx.Kernel.GetDefault<IDataRetrievalService>()))
    .InSingletonScope()
    .Named("BaseSearchService");

Bind<ISearchService>()
    .ToMethod(ctx => new HttpSearchService(
        ctx.Kernel.GetNamedOrDefault<ISearchService>("BaseSearchService"),
        HttpContext.Current))
    .InRequestScope();

GetNamedOrDefault is an extension method we have:

public static T GetDefault<T>(this IKernel kernel)
{
    return kernel.Get<T>(m => m.Name == null);
}

public static object GetDefault(this IKernel kernel, Type type)
{
    return kernel.Get(type, m => m.Name == null);
}

public static T GetNamedOrDefault<T>(this IKernel kernel, string name)
{
    T result = kernel.TryGet<T>(name);

    if (result != null)
        return result;

    return kernel.GetDefault<T>();
}

public static object GetNamedOrDefault(this IKernel kernel, Type type, string name)
{
    var result = kernel.TryGet(type, name);

    if (result != null)
        return result;

    return kernel.GetDefault(type);
}

How best are we to represent this in Ninject? Should we use "WhenParentNamed" and let Ninject decide what object to pass to the constructor?

Likewise, how do we bind the current HttpContext.Current object so that Ninject knows to use that whenever a constructor takes a HttpContext object as one of its parameters? Should it be the same as seen here?

https://github.com/ninject/ninject.web.mvc/blob/master/mvc3/src/Ninject.Web.Mvc/MvcModule.cs

If we are making use of the request scope, should we be using the OnePerRequestModule and configuring this in the Web.config of the application?

Should we also use:

https://github.com/ninject/Ninject.Web.Common/blob/master/src/Ninject.Web.Common/NinjectHttpApplication.cs

To ensure our objects are disposed properly?

This may seem quite simplistic to some but I just want to be clear on the approach everyone takes.

Thanks


回答1:


In case of decoration using some conditional binding (e.g. WhenParentNamed, WhenClassHas, WhenTargetHas or a custon When) is the best way to go.

Bind<ISearchService>()
  .To<BaseSearchService>()
  .InSingletonScope()
  .WhenParentNamed("HttpServiceDecorator");

Bind<ISearchService>()
    .To<HttpSearchService>()
    .Named("HttpServiceDecorator")
    .InRequestScope();

Bind<HttpContext>().ToMethod(ctx => HttpContext.Current);

The best way to get the service is to inject it to the constructor of the class that needs it. There is nothing special necessary to receive an instance of HttpSearchService. It will be passed as default.

Since Ninject.Web 2.2 the OnePerRequestModule is used by default. So no change is required.

Ninject.Web.Common is introduced for the upcomming Ninject 2.4 release. It is a base component used by all web extensions. This means as long as you stay on 2.2 you must not use it. As soon as you switch to 2.4 (or a 2.3 development build) will have to use it.



来源:https://stackoverflow.com/questions/6627894/configuring-ninject

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!