tags:

views:

61

answers:

1

I have a generic class (GenericClass) which is having a dependency depending on the generic type (IGenericDependency). This dependency is also generic.

public class GenericClass<T>
{
      private readonly IGenericDependency;
}

The type parameter is not known until runtime.

So far I've done this:

I'm injecting a Func.

public class GenericClass<T> : IGenericClass<T> where T:class , new()
{
      private readonly IGenericDependency _genericDependency;

      public GenericClass(Func<TypeIGenericDependency>> factory)
      {
            _genericDependency = factory(T);
      }
}

And the reistration code:

  builder.RegisterGeneric(typeof (GenericClass<>)).As(typeof (IGenericClass<>));

  builder.Register<Func<Type, IGetDataCollection>>(c =>
  {
        var context = c.Resolve<IComponentContext>();
        return type =>
               {
                    if(type.Name.EndsWith("Entity"))
                    {
                        return (IGenericDependency)
                           context.Resolve(typeof (GetEntityCollection<>)
                           .MakeGenericType(type));
                    }
                    if(type.Name.EndsWith("TypedList"))
                    {
                        return (IGenericDependency)
                           context.Resolve(typeof (GetTypedList<>)
                           .MakeGenericType(type));
                    }
                    throw new NotSupportedException("Not supported type");
                };
  });

I'm wondering if there is another way to do this.

+3  A: 

If you're using a recent build, you can use make IGenericDependency generic, e.g. IGenericDependency<T> then use generic type constraints to discriminate between the implementations:

public class GetTypedList<T> : IGenericDependency<T>
    where T : TypedList {
}

public class GetEntity<T> : IGenericDependency<T>
    where T : Entity {
}

GenericClass<T> then depends directly on IGenericDependency<T>.

So long as TypedList and Entity are mutually exclusive types, Autofac will choose the correct implementation.

HTH

Nicholas Blumhardt
Wow, I knew there must be some neater solution :-) This saves a lot of code. Should be as an example in the wiki.