温莎城堡注册与相同服务匹配的组件

本文关键字:服务 组件 城堡 注册 | 更新日期: 2023-09-27 17:55:37

我的MVC应用程序中有以下代码,运行良好。

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

温莎城堡创建组件

CountryService / CountryServiceBase

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

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

我的问题是我有很多课程要注册。所以使用温莎城堡我做了以下事情:

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

温莎城堡创建我的组件

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

但是我的MVC应用程序等待国家服务/国家服务基地,我不知道如何向温莎城堡指定它可以将CountryServiceBase与CountryService匹配,因为这两个类(其中一个是抽象的)继承了ServiceBase

甚至可能吗?

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

温莎城堡注册与相同服务匹配的组件

通常服务是接口。这就是为什么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());

这个解决方案非常快速和肮脏,但至少它解决了你的问题。

如果你CountryServiceBase类是抽象的,使用 Classes 而不是 Types 应该有助于避免注册基类(请参阅此处):

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

但是,看起来您无法避免在注册中提及CountryServiceBase,也许使用OrBasedOn(CountryServiceBase)那么您的实现将同时提供ServiceBase<>CountryServiceBase

可以使用反射来获取从 serviceBase 继承的所有类。你可以在这里找到一种方法来做到这一点

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