3

For various reasons I am trying to upgrade a project from an old version of Castle to v 2.5.3 (I cannot move to v3 due to breaking changes) and am encountering an issue with a generic component that is remoted:

   Container.Register(Component.For(typeof(IStore<>))
        .Named("GenericStore")
        .AddAttributeDescriptor("remoteserver", "RecoverableComponent")
        .AddAttributeDescriptor("marshalByRefProxy", "true")
        .ImplementedBy(typeof(MyStore<>)));

The component appears to register OK, but at the point I attempt to resolve:

   Container.Resolve<IStore<Users>>()

I get an exception "an item with the same key has already been added" and the stack trace (shortened):

at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.System.Collections.IDictionary.Add(Object key, Object value)
at Castle.Facilities.Remoting.RemotingInspector.ConfigureServerComponent(RemotingStrategy server, Type type, ComponentModel model)
at Castle.Facilities.Remoting.RemotingInspector.ProcessModel(IKernel kernel, ComponentModel model)
at Castle.MicroKernel.ModelBuilder.DefaultComponentModelBuilder.BuildModel(String key, Type service, Type classType, IDictionary extendedProperties)
at Castle.MicroKernel.Handlers.DefaultGenericHandler.GetSubHandler(CreationContext context, Type genericType)
at Castle.MicroKernel.Handlers.DefaultGenericHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired)
at Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context, Boolean instanceRequired)
at Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context)

As you can see from the stack trace, it appears to be "building the model" (call to DefaultComponentModelBuilder) again.

Am I registering my component incorrectly?

I've downloaded some of the source code to try and find what I am doing wrong, but wonder if it is actually an issue caused by a combination of Generic and Remoting?

The exception is caused by Castle.Facilities.Remoting.RemotingInspector trying to add properties to the ExtendedProperties dictionary that alreadt exist. In Castle.MicroKernel.Handlers.DefaultGenericHander it doesn't appear to be detecting the fact that the model already exists (is it me or is nothing ever actually added to the Dictionary type2SubHandler?).

Can anyone tell me if I am doing anything wrong, or is there actually a bug?

Mark Dickinson
  • 6,573
  • 4
  • 29
  • 41
oatsoda
  • 2,088
  • 2
  • 26
  • 49
  • ddi you ever fix this? I'm getting a similar error –  May 17 '12 at 15:09
  • Not really, but I am pretty sure that the only solution I found was to register each one explicitly so `Component.For(typeof(IStore)` rather than `Component.For(typeof(IStore<>)`. It appeared that Castle had a problem with resolving for something without explicit generic type parameters. – oatsoda May 18 '12 at 10:21
  • I think mine was because I had registered one service alone then had the service forwarded in another config so basically could be seen as re-registering it? Not sure... Still looking into it –  May 18 '12 at 10:57
  • Are you upgrading? And which version - 2.5.3 or 3? – oatsoda May 21 '12 at 10:57

1 Answers1

3

My humble suggestion is that it is not a problem with Castle Windsor at all. Probably you have a static dictionary defined in the component that Castle Windsor tries to resolve which dictionary(or other collection with uniqe key constraint) has a diplicate key. Probably from copy-paste operation. you will get this error if you try to instantiate the class by hand. The code may look like this :

public class MissTypedDictionaryClass
{
... some ctors here
... some other methods and props

... and somewhere here lies the mistyped dict
    private static readonly Dictionary<string, string> MyDeclaredDict = new Dictionary<string, string>()
    {
        {"Key1", "Val1"},
        {"Key2", "Val2"},
        {"Key1", "Val3"}, // Here is the problem.
    };
 }
Ognyan Dimitrov
  • 6,026
  • 1
  • 48
  • 70