Castle Windsor注册与相同服务匹配的组件

时间:2015-06-12 15:07:08

标签: c# asp.net-mvc castle-windsor

我的MVC应用程序中有以下代码可以正常工作。

container.Register(Component.For<CountryServiceBase>()
    .ImplementedBy<CountryService>()
    .LifestylePerWebRequest());

Castle Windsor创建一个组件

CountryService / CountryServiceBase

我的控制器在这里获取一个实例化对象:

public class MyController : MainController
{
    public CountryServiceBase CountryService {get; set;} // instantiate by Ioc : OK

我的问题是我有很多课程需要注册。所以使用Castle Windsor我做了以下事情:

container.Register(
    Types
    .FromAssemblyNamed("mynamespace")
    .BasedOn(typeof(ServiceBase<>))
    .WithService.Base()
    .LifestylePerWebRequest());

Castle Windsor创建我的组件

CountryService / ServiceBase<Country>
CountryServiceBase / ServiceBase<Country>

但我的MVC应用程序等待CountryService / CountryServiceBase,我不知道如何指定Castle Windsor它可以将CountryServiceBase与CountryService匹配,因为这两个类(其中一个是抽象类)继承ServiceBase < / p>

甚至可能吗?

注意:我发布了一个类似的问题,但我的调查结果更准确,所以我删除了旧的。

3 个答案:

答案 0 :(得分:1)

通常services是接口。这就是为什么AllInterfaces()适用于其他人的原因。

如果您检查API,则会找到可以轻松使用的Select()方法。

  

如果上述选项都不适合您,您可以提供自己的选项   选择逻辑作为委托并将其传递给WithService.Select()   方法

因此注册码可能如下:

    container.Register(Types.FromThisAssembly()
        .BasedOn(typeof(ServiceBase<>))
        .WithService.AllInterfaces()
        .WithService.Select((t, b) => t.BaseType != null
                ? new[] { t.BaseType }
                : new Type[0])
        .LifestylePerWebRequest());

这个解决方案非常快速,但至少可以解决您的问题。

答案 1 :(得分:0)

如果您的CountryServiceBase类是抽象的,那么使用Classes代替Types应该有助于避免注册基类(请参阅here):

  

另一方面,类预先过滤类型以仅考虑非抽象类

但是,您似乎不能避免在注册时提及CountryServiceBase,也许使用OrBasedOn(CountryServiceBase),那么您的实施将同时以ServiceBase<>CountryServiceBase提供。< / p>

答案 2 :(得分:0)

您可以使用反射来获取从serviceBase继承的所有类。 您可以找到执行此操作的方法here

然后,您可以实现上面的代码来实例化所有服务。