Ninject does not trigger method when binding to method?

感情迁移 提交于 2019-12-13 07:36:45

问题


The ViewModel depends on a list of MyObject which is bound to a Repository method that looks like it never gets called?

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(); }
}

The NHibernateRepository is an abstract class which exposes protected members allowing one to customize the method names through interfaces like IMyObjectsRepository to state a more domain friendly name, let's say.

The objects mappings work fine as NHibernate has properly created and updated the underlying database doing Domain-Driven Design.

The problem is definitely around my understanding or misuse (I believe) of Ninject while binding the list of MyObject to the Repository method.

  • I've put a breakpoint to the FindAllMyObjects method, and it never gets hit?

  • and the list of MyObjects being injected into the MyObjectsManagementViewModel constructor is always an empty one?


回答1:


I think the issue here is you are binding to a type (IList<T>) that Ninject isn't expecting to resolve. the simplest solution is to instead bind to a Func that will return the object(s) you want.

for example:

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

then:

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

this effectively does a lazy-load of the items from the repository when the MyObjectsViewModel object is constructed.

another alternative (which may be more clear and better design) would be to create a new interface like IMyObjectProvider, which is responsible only for finding and returning the correct data. then that interface would be injected into your viewmodel instead of the actual model objects.



来源:https://stackoverflow.com/questions/29063164/ninject-does-not-trigger-method-when-binding-to-method

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