Register types based on base class

烈酒焚心 提交于 2019-11-30 07:42:13

问题


I'm trying to figure out Windsor as an IOC container. The problem I'm facing right now is to register all of my viewmodels at once.

I've taken a look at the docs and thought that the following code should work. However, when I check the container afterwards, nothing is registered.

container.Register(Classes.FromThisAssembly()
                          .BasedOn<ViewModelBase>()
                          .LifestyleTransient());

where ViewModelBase is my baseclass.

Also tried the following:

container.Register(Classes.FromThisAssembly()
         .InSameNamespaceAs<MainWindowViewModel>()
         .LifestyleTransient()); 

The necessary dependencies can be resolved, the viewmodels not. I suppose I'm missing something obvious here?

Edit

My dependencies are registered as follows:

this.container.Register(Component.For<IDALHandler>().ImplementedBy<DALHandler>());
this.container.Register(Component.For<IBLHandler>().ImplementedBy<BLHandler>());

UPDATE

Since the suggestions didn't work, I was planning on adding the code from my baseclass and viewmodel here. While doing so I noticed that my viewmodel-class was internal sealed. When changing it to public sealed, the above code did work.

Can someone explain why internal classes can't be registered in the container? I've already tested other IOC containers with the exact same setup and they didn't complain about it.


回答1:


Your example of registration started working well in my application when I added selection of the service for component. E.g. .WithService.AllInterfaces()

container.Register(Classes.FromThisAssembly()
    .BasedOn(typeof(MyBaseClass<>))
    .WithService.AllInterfaces()
    .LifestylePerWebRequest()
);

container.Register(Classes.FromThisAssembly()
    .InSameNamespaceAs<MyBaseClass>()
    .WithService.AllInterfaces()
    .LifestylePerWebRequest()
);

UPDATE:

In order to register internal types, .IncludeNonPublicTypes() should be used.

public class ExampleTest
{
    [Test]
    public void MyBaseClass_Base()
    {
        var target = new WindsorContainer();

        target.Register(Classes.FromThisAssembly()
            .IncludeNonPublicTypes()
            .BasedOn(typeof(MyBaseClass<>))
            .WithService.Base()
            //.LifestylePerWebRequest()
        );

        //assert
        target.Resolve<MyBaseClass<int>>().Should().BeOfType<A>();
        target.Resolve<MyBaseClass<string>>().Should().BeOfType<B>();
    }

    [Test]
    public void MyBaseClass_Self()
    {
        var target = new WindsorContainer();

        target.Register(Classes.FromThisAssembly()
            .IncludeNonPublicTypes()
            .BasedOn(typeof(MyBaseClass<>))
            .WithService.Self()
            //.LifestylePerWebRequest()
        );

        //assert
        target.Resolve<MyBaseClass<int>>().Should().BeOfType<MyBaseClass<int>>();
        target.Resolve<MyBaseClass<string>>().Should().BeOfType<MyBaseClass<string>>();
        target.Resolve<A>().Should().BeOfType<A>();
        target.Resolve<B>().Should().BeOfType<B>();
    }
}

internal class MyBaseClass<T>
{
}

internal class A : MyBaseClass<int>
{
}

internal class B : MyBaseClass<string>
{
}



回答2:


My guess is your viewmodels have been registered in the container, but they are not resolvable through their interface.

Set a breakpoint after the registration and check if container has been filled as expected.

UPDATE as per my comment below: Keep in mind "group" registration (Classes.) skips internal class.

If they have been registered, let say you have a ViewModel like this

public class MyViewModel1 : ViewModelBase, IMyViewModel1


container.Resolve<MyViewModel1>() // resolve

container.Resolve<IMyViewModel1>() // no resolve

to accomplish the second resolving scenario you have to do what Ilya pointed about about adding WithService during registration, so you can resolve by interface instead of by concrete.



来源:https://stackoverflow.com/questions/20349269/register-types-based-on-base-class

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