【问题标题】:Ninject does not trigger method when binding to method?Ninject 绑定到方法时不触发方法?
【发布时间】:2015-03-17 21:52:27
【问题描述】:

ViewModel 依赖于一个 MyObject 列表,该列表绑定到一个看起来永远不会被调用的 Repository 方法?

CompositionRoot

public sealed class CompositionRoot {
    public CompositionRoot(IKernel kernel) {
        if (kernel == null) throw new ArgumentNullException("kernel");
        this.kernel = kernel;
    }

    public void ComposeObjectGraph() {
        BindRepositoriesByConvention();
        BindDomainModel();
    }

    private void BindDomainModel() {
        kernel
            .Bind<IList<MyObject>>()
            .ToMethod(ctx => ctx.Kernel.Get<IMyObjectsRepository>().FindAllMyObjects())
            .WhenInjectedInto<MyObjectsManagementViewModel>();
    }

    private void BindRepositoriesByConvention() {
        kernel.Bind(s => s
            .FromThisAssembly()
            .SelectAllClasses()
            .EndingWith("Repository")
            .BindSelection((type, baseType) => type
                .GetInterfaces()
                .Where(iface => iface.Name.EndsWith("Repository"))));
    }

    private readonly IKernel kernel;
}

MyObjectsManagementViewModel

public class MyObjectsManagementViewModel {
    public MyObjectsViewModel(IList<MyObject> model) {
        if (model == null) throw new ArgumentNullException("model");
        Model = model;
    }

    public MyObject Current { get; set; }
    public IList<MyObject> Model { get; set; }
}

MyObjectsRepository

public class MyObjectsRepository 
    : NHibernateRepository<MyObject>
    , IMyObjectsRepository {
    public MyObjectsRepository(ISession session) : base(session) { }

    public IList<MyObject> FindAllMyObjects() { return GetAll(); }
}

NHibernateRepository 是一个抽象类,它公开受保护的成员,允许人们通过诸如 IMyObjectsRepository 之类的接口自定义方法名称,以声明一个对域更友好的名称,比方说。

对象映射工作正常,因为NHibernate 已正确创建并更新底层数据库,执行Domain-Driven Design

问题肯定是我在将 MyObject 列表绑定到 Repository 方法时对 Ninject 的理解或误用(我相信)。

  • 我在 FindAllMyObjects 方法中设置了一个断点,但它永远不会被命中?

  • 注入到 MyObjectsManagementViewModel 构造函数中的 MyObjects 列表始终为空?

【问题讨论】:

    标签: c# .net ninject


    【解决方案1】:

    我认为这里的问题是您绑定到 Ninject 不希望解决的类型 (IList&lt;T&gt;)。最简单的解决方案是绑定到将返回所需对象的 Func。

    例如:

    kernel
        .Bind<Func<IList<MyObject>>>()
        .ToMethod(ctx => () => ctx.Kernel.Get<IMyObjectsRepository>().FindAllMyObjects())
        .WhenInjectedInto<MyObjectsManagementViewModel>();
    

    然后:

    public MyObjectsViewModel(Func<IList<MyObject>> model) {
        if (model == null) throw new ArgumentNullException("model");
        Model = model();
    }
    

    当 MyObjectsViewModel 对象被构造时,这有效地从存储库中延迟加载项目。

    另一种选择(可能更清晰和更好的设计)是创建一个新接口,如IMyObjectProvider,它只负责查找和返回正确的数据。那么该接口将被注入到您的视图模型中,而不是实际的模型对象中。

    【讨论】:

    • 注入IMyObjectProvider 与注入IMyObjectRepository 不同吗?我在 Internet 上的某个地方读到,将存储库注入视图模型类被认为是一种反模式,不是吗?
    • 真的,如果您以 MVC 或 MVP 模式应该使用的方式使用视图模型,它不应该有 任何 依赖项。您将拥有一个控制器或演示者,它正在创建并使用存储库(或任何地方)中的数据填充它。但是,您问了一个关于为什么 Ninject 没有填写请求的问题。
    猜你喜欢
    • 1970-01-01
    • 2011-04-26
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多