Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
165 views
in Technique[技术] by (71.8m points)

c# - Ninject does not trigger method when binding to method?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...