解决温莎城堡中“超级接口”的实现

也许甚至不可能,但这是我的需要。
我有一个密钥映射器的通用实现,还有一个能够生成此类映射器的Factory类

public class KeyMapperFactory 
{
    IKeyMapper<TInternalKey,TExternalKey> GetMapper<TInternalKey,TExternalKey>(MapperConfig config)
}

现在,我希望在应用程序中具有“说清楚”的界面,因此我可以在应用程序中像这样创建另一个空界面

public interface IMapCompanyToPayrollCompany : IKeyMapper<CompanyId,PayrollCompanyId>
{
}

我是否有机会以这种(错误的)方式使用CastleWindsor创建IMapCompanyToPayrollCompany的“即时”实现?

var mapperConfig = MapperConfig {
...
};
var keyMapperFactory = new KeyMapperFactory();
var container = new WindsorContainer();

container.Register(
    Component
        .For<IMapCompanyToPayrollCompany>()
        .UsingFactoryMethod(kernel => (IMapCompanyToPayrollCompany)keyMapperFactory.GetMapper<CompanyId,PayrollCompanyId>(mapperConfig)
);
wxcool87 回答:解决温莎城堡中“超级接口”的实现

我使用Castle的DynamicProxies找到了解决方案

// I developed an extension method on the IWindsorContainer
public static void RegisterMapper<TSpeakingInterface,TInternal,TExternal>(this IWindsorContainer container,MapperConfig config) 
    where TSpeakingInterface : IKeyMapper<TInternal,TExternal>
{
    container.Register(
        Component
            .For<IMapCompanyToPayrollCompany>()
            .UsingFactoryMethod(() => {
                var generator = new ProxyGenerator(); // <--Documentation recommend this to be a Singleton for performance and memory reason ... 
                var keyMapperFactory = new KeyMapperFactory();
                var mapper = keyMapperFactory.GetMapper<TInternal,TExternal>(config);
                var interceptor = new KeyMapperInterceptor<TInternal,TExternal>(mapper);

                // see: https://github.com/castleproject/Windsor/issues/224
                var nullProxy = generator.CreateInterfaceProxyWithoutTarget<TSpeakingInterface>();
                return generator.CreateInterfaceProxyWithTarget(nullProxy,interceptor);
            })
    );
}

// Now I can register a mapper this way:
var container = new WindsorContainer();
var config = new MapperConfig {
    [...] // mapper config stuff here
}
container.RegisterMapper<IMapCompanyToPayrollCompany,CompanyId,PayrollCompanyId>(config);

拦截器很简单

public class KeyMapperInterceptor<TInternal,TExternal> : IInterceptor
{
   private readonly IKeyMapper<TInternal,TExternal> realMapper;

   public KeyMapperInterceptor(IKeyMapper<TInternal,TExternal> realMapper)
   {
       this.realMapper = realMapper;
   }

    public void Intercept(IInvocation invocation)
    {
       // We simply call the corresponding method on the realMapper
       var method = invocation.Method;
       invocation.ReturnValue = method.Invoke(realMapper,invocation.Arguments);
    }
}

...并且有效! 当然,IMapCompanyToPayrollCompany中不允许使用其他方法或属性,因为拦截器将尝试在不了解任何内容的“ realMapper”上执行/访问它们!

本文链接:https://www.f2er.com/3158466.html

大家都在问