开发者

Use component id in Castle Windsor generic object configuration

2 questions in one, but very much related.

Is it possible with Castle Windsor to resolve a configuration entry such as -

Assembly.Namespace.Object1`2[[${ComponentId1}],[${ComponentId2}]], Assembly

Where ComponentId1 and ComponentId2 are defined as components. Castle Windsor doesn't开发者_如何学C seem to be resolving the ComponentId, it is just looking for ComponentId1 in the Castle.Windsor assembly.

The second question comes in to play if you can't do the first question. If you have to use a full assembly reference instead of a ComponentId, how can you pass any parameters to the object being created? eg to set ComponentId1.Field1 = "blah", or pass something to the constructor of ComponentId1

Hope that makes sense

Update -

Following the request for code I've knocked together the following -

Objects

public class Wrapper<T, T1> where T : ICollector where T1:IProcessor
{
    private T _collector;
    private T1 _processor;

    public Wrapper(T collector, T1 processor)
    {
        _collector = collector;
        _processor = processor;
    }

    public void GetData()
    {
        _collector.CollectData();
        _processor.ProcessData();
    }

}

public class Collector1 : ICollector
{
    public void CollectData()
    {
        Console.WriteLine("Collecting data from Collector1 ...");
    }
}

public class Processor1 : IProcessor
{
    public void ProcessData()
    {
        Console.WriteLine("Processing data from Processor1  ...");
    }
}

repeated so 3 of each type of object in the example

Config

<components>
<component id="Collector1"
           service="CastleWindsorPlay.ICollector, CastleWindsorPlay"
           type="CastleWindsorPlay.Collector1, CastleWindsorPlay"/>
<component id="Collector2"
           service="CastleWindsorPlay.ICollector, CastleWindsorPlay"
           type="CastleWindsorPlay.Collector2, CastleWindsorPlay"/>
<component id="Collector3"
           service="CastleWindsorPlay.ICollector, CastleWindsorPlay"
           type="CastleWindsorPlay.Collector3, CastleWindsorPlay"/>
<component id="Processor1"
           service="CastleWindsorPlay.IProcessor, CastleWindsorPlay"
           type="CastleWindsorPlay.Processor1, CastleWindsorPlay"/>
<component id="Processor2"
           service="CastleWindsorPlay.IProcessor, CastleWindsorPlay"
           type="CastleWindsorPlay.Processor2, CastleWindsorPlay"/>
<component id="Processor3"
           service="CastleWindsorPlay.IProcessor, CastleWindsorPlay"
           type="CastleWindsorPlay.Processor3, CastleWindsorPlay"/>
<component id="Wrapper1"
           type="CastleWindsorPlay.Wrapper`2[[CastleWindsorPlay.Collector1, CastleWindsorPlay],[CastleWindsorPlay.Processor3, CastleWindsorPlay]], CastleWindsorPlay" />
  </components>

Instantiation

        var wrapper = (Wrapper<ICollector, IProcessor>) container.Resolve("Wrapper1");
        wrapper.GetData();

This brief example errors with this error message though -

Can't create component 'Wrapper1' as it has dependencies to be satisfied. Wrapper1 is waiting for the following dependencies:

Services: - CastleWindsorPlay.Collector1 which was not registered. - CastleWindsorPlay.Processor3 which was not registered.

The curious part about this is that I can get it to resolve Collector1 and Processor3 individually before the call to the wrapper, but the wrapper still can't see them.

This is a basic example, the next thing I'd like to be able to do is when instantiating the Wrapper, set a property on the collector and/or processor. So it could be something like Collector.Id = 10, but set in the config where the wrapper is defined. Setting against the Collector component definition wouldn't work as I'd want to be able to instantiate multiple copies of each Collector, using different Id's

Update 2

What I'm actually trying to do is have -

<components>
<component id="Wrapper1"
           type="CastleWindsorPlay.Wrapper`2[${Collector1}(id=1)],[${Processor3}]], CastleWindsorPlay" />
<component id="Wrapper2"
           type="CastleWindsorPlay.Wrapper`2[${Collector1}(id=3)],[${Processor3}]], CastleWindsorPlay" />
  </components>

Then have another object defined as

<component id="Manager"
           type="CastleWindsorPlay.Manager,CastleWindsorPlay">
  <parameters>
    <wrappers>
      <array>
        <item>${Wrapper1}</item>
        <item>${Wrapper2}</item>
      </array>
    </wrappers>
  </parameters>

Then finally in code just be able to call -

var manager = (Manager)container.Resolve("Manager");

This should return the manager object, with an array of wrappers populated and the wrappers configured with the correct Collector and Convertor.

I know there are errors in the Castle config here, that's why I'm asking the question, I don't know how to set the config up to do what I'm after, or even if it's possible to do it in Castle Windsor


UPDATE2

Ok it's starting to make sense now :) And like I said from the start, it looks like you're looking for service overrides:

<components>
<component id="Wrapper1" type="CastleWindsorPlay.Wrapper`2[<<closing types go here>>]/>
   <parameters>
      <collector>${collector1WithId1}</collector>
      <collector>${processor3WithId3}</collector>
   </parameters>
</component>

<component id="Wrapper2" type="CastleWindsorPlay.Wrapper`2[<<closing types go here>>]/>
   <parameters>
      <collector>${collector1WithId5}</collector>
      <collector>${processor3WithId8}</collector>
   </parameters>
</component>
</components>

UPDATE

Ok, thanks for the example. The reason why you're getting the error, is that you're registering component Collector1 and component Processor3 as service ICollector and IProcessor respectively. You have no service for Collector1 and Processor3 therefore when Windsor tries to provide them, it can't find them hence the exception message.

You need to register them as appropriate services in order for this to work.


I don't know what you're trying to do here, but I assume you're looking for service overrides and inline parameters

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜