I currently have an interface for a single step in a pipeline.
public interface IPipelineStep<T1, T2>
where T1: ModelObject
where T2: EntityObject { }
And I have a whole bunch of steps that implement this interface:
public class ValidateModelStep<T1, T2> : IPipelineStep<T1, T2>
where T1: ModelObject
where T2: EntityObject { }
public class Step2<T1, T2> : IPipelineStep<T1, T2>
where T1: ModelObject
where T2: EntityObject { }
public class Step3<T1, T2> : IPipelineStep<T1, T2>
where T1: ModelObject
where T2: EntityObject { }
public class Step4<T1, T2> : IPipelineStep<T1, T2>
where T1: ModelObject
where T2: EntityObject { }
I am currently registering them like this:
builder.RegisterGeneric(typeof(ValidateModelStep<,>)).As(typeof(IPipelineStep<,>)).AsSelf();
builder.RegisterGeneric(typeof(Step2<,>)).As(typeof(IPipelineStep<,>)).AsSelf();
builder.RegisterGeneric(typeof(Step3<,>)).As(typeof(IPipelineStep<,>)).AsSelf();
builder.RegisterGeneric(typeof(Step4<,>)).As(typeof(IPipelineStep<,>)).AsSelf();
And then I can use autofac to instantiate these steps. The problem is, I have many, many steps. And it's very frustrating to have to register each one every time I create a new one.
Is there any way to register them all at once?
I know you can use assembly scanning and AsClosedTypesOf
, but this doesn't seem to work for open generic implementations of open generic interfaces.
Things I have tried:
builder.RegisterAssemblyTypes(myAssembly).AsClosedTypesOf(typeof(IPipelineStep<,>)).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(myAssembly).AssignableTo(typeof(IPipelineStep<,>)).As(typeof(IPipelineStep<,>)).AsSelf();
builder.RegisterAssemblyTypes(myAssembly)
.Where(t => t.IsAssignableFrom(typeof(IPipelineStep<,>)))
.As(typeof(IPipelineStep<,>)).AsSelf();
Is there any way to use AsClosedTypesOf
when the implementation of the interface must also contain generics?
Thanks in advance
I suppose the most straightforward way is to just scan assembly yourself:
foreach (var t in myAssembly.GetTypes()
.Where(c => !c.IsInterface && c.IsGenericTypeDefinition && c.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IPipelineStep<,>)))) {
builder.RegisterGeneric(t).As(typeof(IPipelineStep<,>)).AsSelf();
}
This basically filters types which are open generic and implement IPipelineStep<>
, then registers in container. I guess you can do similar thing with RegisterAssemblyTypes.Where(...)
if you prefer.