Ninject使用InRequestScope处理订单

时间:2012-07-17 00:05:45

标签: asp.net-mvc dependency-injection ninject

刚开始玩ninject - 我无法解决这个问题。考虑这个设置:

private static void RegisterServices(IKernel kernel)
{
   kernel.Bind<IDataTransaction>().To<DataTransaction>().InRequestScope();

   kernel.Bind<IdbAnalytics>().To<dbAnalytics>().InRequestScope();
   kernel.Bind<IdbMembership>().To<dbMembership>().InRequestScope();

   kernel.Bind<IAnalyticsWork>().To<AnalyticsWork>().InRequestScope();
   kernel.Bind<IMembershipWork>().To<MembershipWork>().InRequestScope();

   kernel.Bind<ILog>().To<Log>().InRequestScope();
   ...
}

将Log注入上述类:

public class AnalyticsWork : IAnalyticsWork, IDisposable
{
    private readonly IdbAnalytics _Context;
    private readonly ILog _Log;

    public AnalyticsWork(IdbAnalytics Context, ILog Log)
    {            
        _Context = Context;
        _Log = Log;
        _Log.Write(LogEntryType.DEBUG, "Object Created");
    }
    ...
}

此问题是Log对象在其他对象(AnalyticsWork / MembershipWork)之前被丢弃。有没有办法设置应该处理项目的顺序?或者这个设置有缺陷吗?

1 个答案:

答案 0 :(得分:2)

我不使用NInject,但听起来你注册Log具体是共享或每个web请求(根据InRequestScope可能表明,我再次为不使用NInject道歉,所以我是不确定那是做什么的。)

对于我使用的所有记录器,NLog,Log4Net,MS'记录应用程序块等 - 它们都需要Transient注册,而不是Scoped,因为它们采用启动它们的超类在日志中写出作为调用类。

就处置订单而言,我认为您无法控制任何IoC容器,因为如果另一个类仍然依赖,则该对象不能以不同的顺序处理。几年前,当我第一次使用IoC容器时,我遇到了同样的问题,并且想:“是的,我会将所有内容都注册为范围!”呵呵,这种方法效果不佳。

我想说你的对象只需要以不同的方式注册。仅限制您确实需要作用域的项目,其他所有内容为transientssingletons。我通常遵循以下模式:

  

对所有内容singleton和代码thread-safe进行编码   如果不是线程安全的,请将其设为transient并将其注册为。

如果我没有在我的unit-of-work中使用ORM模式,我通常会将我的ORM容器注册为Scoped,以便他们可以跟踪请求生命周期中的对象更改,以及SaveChanges()后者(例如Entity Framework 4,或NHibernate的Session等)。

相关问题