简体   繁体   English

Castle Windsor:当我的装配无法访问基础类型时,如何注册工厂方法?

[英]Castle Windsor: How do I register a factory method, when the underlying type isn't accessible to my assembly?

I have a project where my business layer is constructed using DI, but I'm trying to go an additional step and use Windsor to manage object construction. 我有一个项目,其中我的业务层是使用DI构建的,但我正在尝试额外的步骤并使用Windsor来管理对象构造。

Let's just say I have a pre-existing data layer (that I don't want to modify), that can be accessed via the following interface: 我们只是说我有一个预先存在的数据层(我不想修改),可以通过以下界面访问:

interface IDataFactory {
   IDataService Service { get; }
}

A series of classes in my business layer depend on the services exposed through IDataFactory: 我的业务层中的一系列类依赖于通过IDataFactory公开的服务:

IFactory factory = DataFactory.NewFactory();
IBusinessService service = new ConcreteBusinessService(factory.Service);

I understand that in order to register IBusinessService to the Castle Windsor container, I'd use code similar to this: 我知道为了将IBusinessService注册到Castle Windsor容器,我会使用类似于此的代码:

IWindsorContainer container = new WindsorContainer();
container.AddComponent("businessService", typeof(IBusinessService), typeof(ConcreteBusinessService));

But for the life of me, I can't figure out how to register services from my data layer, using the my existing factory object. 但对于我的生活,我无法弄清楚如何使用我现有的工厂对象从我的数据层注册服务。 In essence, I'd like to say: 从本质上讲,我想说:

container.AddComponent("dataService", typeof(IDataService), factory.service);

Windsor seems to want me to say container.AddComponent("dataService", typeof(IDataService), typeOf(SomeConcreteDataService) ), but in this instance, ConcreteDataService is internal to that assembly, and thus not accessible in mine. Windsor似乎要我说容器.AddComponent(“dataService”,typeof(IDataService),typeOf(SomeConcreteDataService) ),但在这个实例中,ConcreteDataService是该程序集的内部,因此在我的程序中无法访问。

How would I go about wiring up the data service, given that SomeConcreteDataService isn't known to my assembly? 鉴于我的程序集不知道SomeConcreteDataService,我将如何进行数据服务的连接?


This question is very similar to my own, except in my case, the AddComponent("calculator", typeof(ICalcService), typeof(CalculatorService), "Create"); 这个问题与我自己的问题非常类似,除了我的情况,AddComponent(“计算器”,typeof(ICalcService),typeof(CalculatorService),“Create”); call wouldn't work -- CalculatorService would be internal to another assembly, not available to the assembly wiring up the container. 调用不起作用 - CalculatorService将在另一个程序集内部,不可用于组件连接容器。

Using Windsor 2.0: 使用Windsor 2.0:

[TestFixture]
public class WindsorTests {
    public interface IDataService {}

    public class DataService: IDataService {}

    public interface IDataFactory {
        IDataService Service { get; }
    }

    public class DataFactory: IDataFactory {
        public IDataService Service {
            get { return new DataService(); }
        }
    }

    [Test]
    public void FactoryTest() {
        var container = new WindsorContainer();
        container.AddFacility<FactorySupportFacility>();
        container.AddComponent<IDataFactory, DataFactory>();
        container.Register(Component.For<IDataService>().UsingFactory((IDataFactory f) => f.Service));
        var service = container.Resolve<IDataService>();
        Assert.IsInstanceOfType(typeof(DataService), service);
    }
}

See the fluent API wiki page for more information. 有关详细信息,请参阅流畅的API Wiki页面

Got it. 得到它了。 The answer is, you don't need to worry about the implementation type: 答案是,您不必担心实现类型:

    IWindsorContainer container = new WindsorContainer();
    container.AddFacility("factories", new FactorySupportFacility());
    container.AddComponent("standard.interceptor", typeof(StandardInterceptor));
    container.AddComponent("factory", typeof(DataFactory));

    MutableConfiguration config = new MutableConfiguration("dataService");
    config.Attributes["factoryId"] = "factory";
    config.Attributes["factoryCreate"] = "get_Service";
    container.Kernel.ConfigurationStore.AddComponentConfiguration("dataService", config);
    container.Kernel.AddComponent("dataService", typeof(IDataService));

    IDataService dataService = (IDataService) container["dataService"];

I had a "whoa" moment when I saw it execute successfully, because I hadn't passed in the specific implementation type to Kernel.AddComponent() 当我看到它成功执行时,我有一个“哇”的时刻,因为我没有将特定的实现类型传递给Kernel.AddComponent()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM