基于基类注册类型

时间:2013-12-03 10:59:03

标签: castle-windsor ioc-container

我试图找出温莎作为IOC容器。 我现在面临的问题是立即注册所有的视图模型。

我看了一下这些文档,并认为以下代码应该可行。 但是,当我之后检查容器时,没有注册任何内容。

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

其中ViewModelBase是我的基类。

还尝试了以下内容:

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

可以解决必要的依赖项,而不是viewmodels。 我想我在这里遗漏了一些明显的东西?

修改

我的依赖关系注册如下:

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

更新

由于这些建议不起作用,我计划在这里添加来自我的基类和viewmodel的代码。 在这样做时,我注意到我的viewmodel-class是internal sealed。将其更改为public sealed时,上述代码确实有效。

有人可以解释为什么内部类无法在容器中注册吗? 我已经用完全相同的设置测试了其他IOC容器,他们并没有抱怨它。

2 个答案:

答案 0 :(得分:8)

当我添加selection of the service for component时,您的注册示例开始在我的应用程序中正常运行。例如。的 .WithService.AllInterfaces()

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

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

<强>更新

要注册内部类型,应使用 .IncludeNonPublicTypes()

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>
{
}

答案 1 :(得分:0)

我的猜测是你的viewmodels已在容器中注册,但它们无法通过其界面解析。

在注册后设置断点,并检查容器是否按预期填充。

更新,根据我的评论如下: 请记住“组”注册(Classes。)会跳过内部类。

如果他们已经注册,请假设你有一个像这样的ViewModel

public class MyViewModel1 : ViewModelBase, IMyViewModel1


container.Resolve<MyViewModel1>() // resolve

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

要完成第二个解决方案,您必须执行Ilya在注册期间添加WithService所指出的内容,以便您可以通过界面而不是具体来解决。