2015-06-12 71 views
2

我在我的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应用程序等待一个CountryService/CountryServiceBase,我不知道如何指定温莎城堡是它可以匹配CountryServiceBase到CountryService作为这两个类(其中一个是抽象类)继承ServiceBase

它甚至有可能吗?

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

+0

尝试更改'公共CountryServiceBase CountryService {get;设置;}'通过'公共ServiceBase CountryService {get;设置;}' –

+0

它会工作,但在抽象类CountryServiceBase中,我有几个声明的方法。否则它会起作用。 – AMS

+0

也许'BasedOn(typeof(CountryServiceBase))'? –

回答

0

如果您CountryServiceBase是抽象类,使用Classes代替Types应有助于避免在基类注册(见here):在另一方面

类预过滤器的类型只考虑非抽象类

然而,它并不像你能避免在您的注册提CountryServiceBase,也许使用OrBasedOn(CountryServiceBase)那么你的实施将是一个既可以是ServiceBase<>也可以是CountryServiceBase

0

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

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

+0

这可能是一个想法。我会等待赏金完成,但我喜欢这个解决方案,因为我可以添加服务,而无需在我的项目中创建它们时逐一注册。 – AMS

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

该解决方案是相当快的和肮脏的,但至少它可以解决您的问题。