Castle 多继承选择

Castle 多继承选择

很多时候,我们定义了一个接口,但是这个接口会有多种不同的,这时IOC构造函数注入的时候,就需要自动选择对应的实现。

public interface ITestService {}

public class TestService : IService
{
     public string test()
     {
         return "test"
     }
}

public class TestService_New : ICalculatorService
{
     public string test()
     {
         return "test new";
     }
}

此时,我们大多数情况下,需要用TestService来实现ITestService,但是少部分情况下,需要用TestService_New实现ITestService。

解决方案一

IOC中只实现需要用到的类:

Component.For<ITestService>()
    .ImplementedBy<TestService>() 

如果在某些地方部署时,修改为
Component.For()
.ImplementedBy()

这样每次部署的时候都需要修改代码,而且需要手写的规则会越来越多。

解决方案二

参考了Castle的WIKI,发现了可以ServiceOverrides重写实现:

 Component.For<ITestService>()
    .ImplementedBy<TestService>() 
    .Named("myservice.default"),
Component.For<ITestService>()
    .ImplementedBy<TestService_New>()
    .Named("myservice.new"),

Component.For<TestController>()
    .ServiceOverrides(ServiceOverride.ForKey("myService").Eq("myservice.new"))

尝试了一下,VS提示改方法已过世,建议使用Dependency.OnComponent代替。
Component.For().
.DependsOn(Dependency.OnComponent<ITestService, TestService_New>())

修改代码之后,怎么都不起作用。重新翻看官方WIKI,发现了IsDefault方法,当多个类实现同一个接口时,可以通过IsDefault来置为默认实现。

解决方案三

             //先通过DefaultInterfaces加载正常实现 
             Classes.FromAssembly(assembly)
             .IncludeNonPublicTypes()
             .BasedOn<IApplicationService>()
             .WithService.DefaultInterfaces()
             .LifestyleTransient()
             .Configure(c =>
             {
                 c.Interceptors<ExceptionInterceptor, TransactionInterceptor>();
                 c.Named(c.Implementation.Name);
             }),
             //根据WEBCONFIG加载特殊实现,并设置为默认实现
             Classes.FromAssembly(assembly)
            .IncludeNonPublicTypes()
            .BasedOn<IApplicationService>()
            .WithService.Select((type, @base) =>
                      type.GetAllInterfaces()
                          .Where(i => type.Name.Contains(GetInterfaceNameFromConf(i))))
            .LifestyleTransient()
            .Configure(c =>
            {
                c.Interceptors<ExceptionInterceptor, TransactionInterceptor>().IsDefault()
                .Named(c.Implementation.FullName +  "_" + ConfigurationManager.AppSettings["City"]);
            })


            private string GetInterfaceNameFromConf(Type @interface)
            {
                var name = @interface.Name;
                if ((name.Length > 1 && name[0] == 'I') && char.IsUpper(name[1]))
                {
                    return name.Substring(1) + "_" + ConfigurationManager.AppSettings["City"];
                }
                return name;
            }

OK,大功告成。

转载于:https://www.cnblogs.com/lazio10000/p/5266876.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值