Windsor组件注册基于通用接口

时间:2013-07-23 19:36:43

标签: .net castle-windsor ioc-container

我正在尝试注册与Windsor容器共享相同接口ISetting的多种类型。

澄清ISetting界面不需要任何实施。它的唯一目的是帮助在装配体中找到设置类型。否则,这些设置类型不会以任何方式,形状或形式相互关联。

通常我会逐行创建这些类型的代码:

var settingsManager = new SettingsManager();
var applicationSettings = settingsManager.LoadSettings<ApplicationSettings>();
var emailSettings = settingsManager.LoadSettings<EmailSettings>();

但我想按惯例注册这些组件,所以我不必手动完成。

到目前为止,我在WindsorInstallers之一中有以下代码:

    container.Register( Classes.FromAssemblyContaining<ISetting>()
                                   .BasedOn<ISetting>()
                                   ...help...
                                   );

澄清:设置将在类中用作具体类型(见下文)

public class Service2
{
    private readonly EmailSettings _settings;

    public Service2(EmailSettings settings)
    {
        _settings = settings;
    }

    public void Awesome()
    {
        Console.WriteLine(_settings.Value);
    }
}

我的目标:即使我可以逐个将所有设置类型注入容器,我正在寻找一个解决方案,我可以找到并注册从{{1}继承的所有类型使用一个(可能是两个)语句。

1 个答案:

答案 0 :(得分:5)

这取决于你想如何使用它(注入它)

这是一个可能的解决方案

container.Register(
Classes
    .FromThisAssembly()
    .BasedOn<ISettings>()
    .WithServiceSelf()  //for way 3
    .WithServiceFirstInterface() //way 1 & 2
    .Configure(c => c.Named(c.Implementation.Name)) //way 1 & 2
    );

方式1 - 直接解决 - 我认为你不会使用这个

在您的示例中,您直接获取设置,您可以使用带有容器的命名参数,如下所示

var settings = container.Resolve<ISettings>("EmailSettings");

以这种方式解析设置时,我们使用命名参数来选择正确的实现。

方式2 - 使用命名参数注入

在这种情况下,我们有如下服务(再次猜测可能的用途)

public class Service1
{
    private readonly ISettings _emailSettings;

    public Service1(ISettings emailSettings)
    {
        _emailSettings = emailSettings;
    }

    public void Awesome()
    {
        Console.WriteLine(_emailSettings.Value);
    }
}

要使其工作,我们需要注册此类型以使用带有构造函数参数的命名参数,如下所示:

//using a named parameter
container.Register(
    Component.For<Service1>().ImplementedBy<Service1>()
    .DependsOn(Dependency.OnComponent(typeof(ISettings), "EmailSettings")));

取决于寻找要注入的属性/ ctor params。然后它使用命名的实现。

方式3 - 我们使用直接类型

这种可能的方式假设服务知道它需要具体类型,例如:

public class Service2
{
    private readonly EmailSettings _settings;

    public Service2(EmailSettings settings)
    {
        _settings = settings;
    }

    public void Awesome()
    {
        Console.WriteLine(_settings.Value);
    }
}

此注册的注册与通常相同

//using the actual type
container.Register(Component.For<Service2>().ImplementedBy<Service2>());

关键部分是如何注册您的设置类型。如果我没有满足您的使用,请您提供更多信息。

希望这会有所帮助

相关问题