代码中的 Windsor Setter 注入

发布于 2024-10-03 01:06:02 字数 1542 浏览 8 评论 0原文

我正在使用 Windsor 在 .Net 项目中执行 IoC,但在代码中进行 setter 注入时遇到困难。

我相信这是因为我全面注册了我的组件,因为最终我希望遗留项目将完全符合 IoC 标准并且大部分经过单元测试(美梦!)。

以下是我注册 DAO 的方式:

container
    .Register(AllTypes.FromAssemblyNamed("MyApp.Business")
    .Where(Component.IsInNamespace("MyApp.Business.Dao"))
    .WithService.DefaultInterface());

以下是我使用 DAO 注册组件的方式:

container
    .Register(AllTypes.FromAssemblyNamed("MyApp.Business")
    .Where(Component.IsInNamespace("MyApp.MyComponentObject")));

我希望 setter 能够在组件中自动获取,但我发现的资源似乎显示 setter 需要待定义。

不幸的是,我只在配置 XML 中找到了如何执行此操作的示例,而没有在代码中找到。

我找到了如何在代码中向组件添加参数,但似乎有限制。看起来它必须是一个字符串,即使情况并非如此,似乎它会迫使我逐一声明这些组件,而不仅仅是一揽子注册。如果我不得不这样做,那么代码将会变得庞大,并且不知何故,温莎会失去一些对我的吸引力。

我记得使用 Spring 时,如果声明了一个 bean,自动装配将毫无问题地注入它。

我在这里错过了温莎的一些东西吗?

===============

更多信息:

在将使用 Dao 组件的组件类中,这是我声明 setter 的方式:

private IMyDao dao = null;

public IMyDao Dao
{
  set { this.dao = value;  }
}

我想要 setter 注入的主要原因是因为我不能更改构造函数而不会对旧应用程序产生很大影响。

===============

更新:

已经注释掉了我的大部分注册代码,只留下这个来看看它是否适用于简单的案例场景,但它没有:

//DAOs
container.Register(

Component.For<IMyDao>()
  .ImplementedBy<MyDao>()
    .Named("myDao"),

//Components
Component.For<MyComponentObject>()
  .Parameters(Parameter.ForKey("Dao").Eq("myDao")));

我在其中放置了一个断点代码正在轰炸,并且也在属性的 set 上,并且 DAO 依赖项在我的组件中仍然为 null 并且属性的 set 行是实际上从来没有打电话过。

I'm using Windsor to do IoC in our .Net project, but I'm having difficulties doing setter injection in code.

I believe it comes from the fact that I blanket register my components, since eventually I'm hoping that legacy project will be fully IoC compliant and mostly Unit Tested (sweet dreams!).

Here is how I'm registering the DAOs:

container
    .Register(AllTypes.FromAssemblyNamed("MyApp.Business")
    .Where(Component.IsInNamespace("MyApp.Business.Dao"))
    .WithService.DefaultInterface());

And here is how I'm registering the components using the DAOs:

container
    .Register(AllTypes.FromAssemblyNamed("MyApp.Business")
    .Where(Component.IsInNamespace("MyApp.MyComponentObject")));

I was hoping that the setters would get picked up automatically in the components, but the resources I found seem to show the setters need to be defined.

Unfortunately I've only found examples of how to do that in the configuration XML, not in the code.

I found how to add a parameter to a component in the code but there seem to be limitations. Looks like it has to be a string and even if that's not the case, seems like it would force me to declare those components one by one instead of just blanket registering. That code would become huge if I had to do that and somehow Windsor would lose some of its appeal to me.

I remember using Spring were if a bean was declared autowiring would inject it without any issue.

Am I missing something w/ Windsor here?

===============

More information:

In the component class that will use the Dao component here is how I declare the setter:

private IMyDao dao = null;

public IMyDao Dao
{
  set { this.dao = value;  }
}

The main reason I want to setter inject is because I can't change the constructors without having a pretty impact on the legacy app.

===============

Update:

Have commented out most of my registration code, left just this to see if that works in a simple case scenario and it did not:

//DAOs
container.Register(

Component.For<IMyDao>()
  .ImplementedBy<MyDao>()
    .Named("myDao"),

//Components
Component.For<MyComponentObject>()
  .Parameters(Parameter.ForKey("Dao").Eq("myDao")));

I put a break point where the code is bombing and also on the set of the property and DAO dependency is still null in my component and the set line of the property is actually never called.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

季末如歌 2024-10-10 01:06:02

温莎城堡的二传手注入确实可以正常工作。

[TestClass]
public class SetterInjectionTest
{
    [TestMethod]
    public void TestMethod1()
    {
        var container = new WindsorContainer();
        container.Register(Component.For<IServiceB>().ImplementedBy<ServiceB>());
        container.Register(Component.For<IServiceA>().ImplementedBy<ServiceA>());
        var serviceA = container.Resolve<IServiceA>();

        Assert.IsTrue(serviceA.IsPropertyInjected());
    }
}

public class ServiceA : IServiceA
{
    public IServiceB B { get; set; }

    public bool IsPropertyInjected()
    {
        return B != null;
    }
}

public interface IServiceA
{
    bool IsPropertyInjected();
}

public class ServiceB : IServiceB{}
public interface IServiceB{}

Castle Windsor's setter injection simply does work properly.

[TestClass]
public class SetterInjectionTest
{
    [TestMethod]
    public void TestMethod1()
    {
        var container = new WindsorContainer();
        container.Register(Component.For<IServiceB>().ImplementedBy<ServiceB>());
        container.Register(Component.For<IServiceA>().ImplementedBy<ServiceA>());
        var serviceA = container.Resolve<IServiceA>();

        Assert.IsTrue(serviceA.IsPropertyInjected());
    }
}

public class ServiceA : IServiceA
{
    public IServiceB B { get; set; }

    public bool IsPropertyInjected()
    {
        return B != null;
    }
}

public interface IServiceA
{
    bool IsPropertyInjected();
}

public class ServiceB : IServiceB{}
public interface IServiceB{}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文