【问题标题】:Controlling lifetime of objects created by factory generated by ToFactory()控制由 ToFactory() 生成的工厂创建的对象的生命周期
【发布时间】:2015-11-03 03:42:03
【问题描述】:

我在 MVC 5 WebAPI 应用程序中使用以下与 Ninject 相关的 nuget 包:

Ninject.MVC5

Ninject.Extensions.Factory

ninject.extensions.conventions

我有一个简单的存储库和一个相应的工厂类,如下所示:

public interface ITaskRunner
{
    void Run();
}
public interface IRepository<T> where T: class
{
    T[] GetAll();
}
public interface IRepositoryFactory<T> where T: class
{
    IRepository<T> CreateRepository();
}

我已经使用 Ninject.Extensions.Factory 中的 ToFactory() 设置了 Ninject 绑定,如下所示:

 kernel.Bind<ITaskRunner>().To<TaskRunner>().InSingletonScope();
 kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InRequestScope();
 kernel.Bind<IRepositoryFactory<Contact>>().ToFactory();

我在以下类中使用工厂:

public class TaskRunner : ITaskRunner
{        
    //MyTask is a simple POCO class(not shown for brevity)
    IRepositoryFactory<MyTask> repoFactory = null;
    IRepository<MyTask> repo = null;
    public TaskRunner(IRepositoryFactory<MyTask> repoFactory)
    {
        this.repoFactory = repoFactory;
        repo = repoFactory.CreateRepository();
    }
    //implementation elided
}

我注意到对 repoFactory.CreateRepository() 的调用总是返回与 Ninject 生成的工厂(动态代理)相同的实例。

问题:有没有办法改变/控制这种行为并为“CreateRepository”返回的实例?

在这种特殊情况下,任务可能在多个线程上异步处理,并且存储库不是线程安全的,因此从“CreateRepository”返回的实例的单例行为是不可取的。

【问题讨论】:

  • 您是否安装了Ninject.Extensions.ContextPresevation
  • 不,我没有安装那个

标签: ninject ninject.web.mvc ninject-extensions


【解决方案1】:

我不确定您要达到什么目的,但是您看到的结果是非常预期的,因为您的 TaskRunner 被绑定为 Singleton(因此构造了一次),并且您在 TaskRunner 构造函数中检索您的存储库,这又发生了一次,所以 repo 总是同一个实例。请注意,无论您如何绑定 IRepository 和 IRepositoryFactory,都会发生这种情况,有关详细信息,请参阅 Mark Seemann 的 Captive Dependency 帖子http://blog.ploeh.dk/2014/06/02/captive-dependency/

事实上,如果你需要在构造函数中创建 repo,你可以只注入 IRepository 本身。 Factory 扩展的强大之处在于它允许在运行时解析实例,而不是在构造时。例如,如果您的 TaskRunner 有 Run() 方法,您可以在其中创建存储库,这样每个要运行的任务都可以有自己的实例。

【讨论】:

  • 好点。我过度简化了这个例子。事实上,我想为 repo 工厂(在 ctor 中)维护一个单例,但在 Run() 方法中解析不同的存储库,因为 Run() 将是多线程的。我相信我注意到“CreateRepository”总是会返回相同的 repo 实例。然后我安装了“ContextPreservationExtension”,它似乎提供了所需的行为,即CreateRepository 现在在每次调用时返回不同的 repo 实例。
猜你喜欢
  • 1970-01-01
  • 2016-07-31
  • 2014-12-22
  • 2021-02-07
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 1970-01-01
  • 2011-03-16
相关资源
最近更新 更多