2

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

澄清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);
    }
}

我的目标:尽管我可以将所有设置类型一个一个地注入容器中,但我正在寻找一种解决方案,我可以在其中找到并注册从ISetting使用一个(可能是两个)语句继承的所有类型。

4

1 回答 1

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 参数。然后它使用命名的实现。

方式 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>());

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

希望这可以帮助

于 2013-07-23T23:14:26.807 回答