Register types based on base class

后端 未结 2 480
予麋鹿
予麋鹿 2020-12-17 06:50

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

相关标签:
2条回答
  • 2020-12-17 06:59

    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>
    {
    }
    
    0 讨论(0)
  • 2020-12-17 07:13

    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.

    0 讨论(0)
提交回复
热议问题