所以我一直在努力构建一个解决方案,除了使用Castle DynamicProxy(2.2版)和拦截器之外,只创建某些组件。一切看起来都很棒,除了在这一切结束时我意识到我需要用windsor容器注册这些组件。这是可能的还是我的工作一无所获?
我将制作2个城堡配置来解释我的问题。第一个起作用,而第二个起作用。
第一个配置(这已经有效了一段时间):
<castle>
<facilities>
<facility
id="factory.support"
type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
</facilities>
<components>
<component
id="Factory"
service="Foo.IFactory, Foo"
type="Foo.Local.LocalFactory, Foo.Local" />
<component
id="Loader"
service="Foo.Contracts.ILoader, Foo.Contracts"
type="Foo.Local.Loader, Foo.Local"
factoryId="Factory" factoryCreate="GetLoader" />
</components>
</castle>
第二个配置(我不知道在type属性中放什么,如果没有它,它就不起作用):
<castle>
<facilities>
<facility
id="factory.support"
type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
</facilities>
<components>
<component
id="Factory"
service="Foo.IFactory, Foo"
type="Foo.Remote.RemoteFactory, Foo.Remote" />
<component
id="Loader"
service="Foo.Contracts.ILoader, Foo.Contracts"
type="I DUNNO, WHAT'S THE TYPE?"
factoryId="Factory" factoryCreate="GetLoader" />
</components>
</castle>
所以我的伪装配置注册工厂设施,然后我注册工厂,然后注册我的“ILoader”组件。 “LocalFactory”为ILoader组件创建实际类型,而“RemoteFactory”使用动态代理创建ILoader组件,创建没有目标的代理。即,我使用ProxyGenerator.CreateInterfaceProxyWithoutTarget方法,因此没有底层类。
那么,根据第二个配置注册组件是否有任何希望?
编辑: 不幸的是,目前不能使用流畅的配置API。因此,为了缩小我的问题,是否可以使用XML配置实现此目的?
答案 0 :(得分:2)
我相信这可以通过Fluent Registration API和“UsingFactoryMethod”机制实现。我试图在下面的测试用例中复制你的伪装场景。
<强>更新强>
事实上,这也适用于XML配置。诀窍就是将接口本身列为配置中的“类型”(或者,等效地,仅指定“类型”,因为如果没有明确提供,“服务”将被设置为“类型”)。我已经更新了下面的测试用例,包括一个“TestXml”测试,该测试使用xml配置来实现所需的结果。 “TestFluent”测试使用流畅的注册API来实现它。仅供参考,我在这里使用Castle Windsor 2.0,因为我猜你正在使用它。
using Castle.DynamicProxy;
using Castle.Facilities.FactorySupport;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using NUnit.Framework;
namespace CastleTests
{
public interface ILoader
{
void Load();
}
public interface ILoaderFactory
{
ILoader GetLoader();
}
public class LoaderFactory : ILoaderFactory
{
public ILoader GetLoader()
{
return GetLoaderStatic();
}
public static ILoader GetLoaderStatic()
{
return (ILoader) new ProxyGenerator().CreateInterfaceProxyWithoutTarget(typeof (ILoader));
}
}
[TestFixture]
public class DynamicFactoryTests
{
[Test]
public void TestFluent()
{
using (var container = new WindsorContainer())
{
container.AddFacility<FactorySupportFacility>();
container.Register(
Component.For<ILoader>().UsingFactoryMethod(() => LoaderFactory.GetLoaderStatic())
);
var loader = container.Resolve<ILoader>();
Assert.That(loader.GetType().FullName, Is.EqualTo("Castle.Proxies.ILoaderProxy"));
}
}
[Test]
public void TestXml()
{
using (var container = new WindsorContainer("factory.xml"))
{
var loader = container.Resolve<ILoader>();
Assert.That(loader.GetType().FullName, Is.EqualTo("Castle.Proxies.ILoaderProxy"));
}
}
}
}
“factory.xml”的内容因此是:
<castle>
<facilities>
<facility
id="factory.support"
type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
</facilities>
<components>
<component
id="foo"
service="CastleTests.ILoaderFactory, CastleTests"
type="CastleTests.LoaderFactory, CastleTests" />
<component
id="bar"
type="CastleTests.ILoader, CastleTests"
factoryId="foo" factoryCreate="GetLoader" />
</components>
</castle>