Ninject绑定方法时不触发方法?

Ninject does not trigger method when binding to method?

看起来从未调用过的 ViewModel depends on a list of MyObject which is bound to a 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 是一个抽象 class,它公开了受保护的成员,允许人们通过 IMyObjectsRepository 等接口自定义方法名称,以声明对域更友好的名称,比方说。

对象映射工作正常 NHibernate has properly created and updated the underlying database doing Domain-Driven Design

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

我认为这里的问题是您正在绑定到 Ninject 不希望解析的类型 (IList<T>)。最简单的解决方案是改为绑定到将 return 所需对象的 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 这样的新界面,它只负责查找和 returning 正确的数据。然后该接口将被注入到您的视图模型而不是实际的模型对象中。