Here's what I'm doing so far (code simplified):
public class MyRegistrationSource : IRegistrationSource
{
public MyRegistrationSource(ContainerBuilder builder /*,...*/)
{
// ...
this.builder = builder;
}
public IEnumerable<IComponentRegistration> RegistrationsFor(
Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
// Some checks here
var interfaceType = serviceWithType.ServiceType;
var implementorType = FindTheRightImplementor(interfaceType);
if (myRegisterConditionSatisfied)
{
return Register(implementorType, interfaceType);
}
return Empty;
}
private IEnumerable<IComponentRegistration> Register(Type concrete, Type @interface)
{
var regBuilder = builder.RegisterType(concrete).As(@interface).IfNotRegistered(@interface);
return new[] { regBuilder.CreateRegistration() };
}
}
Then, at startup I'm doing something like
builder.RegisterSource(
new NonRegisteredServicesRegistrationSource(builder/*, ...*/));
The above is intended to register those matching services only when there's no previous registration. I tried doing the registration without using the ContainerBuilder
but couldn't get it to work.
This is working but are there any issues in passing-in the ContainerBuilder
instance to the RegistrationSource
?
Thanks!
I'd probably argue against passing in a ContainerBuilder
.
Every type you register in your source will add a callback to a list of callbacks inside the Container Builder which will never get cleared, potentially creating a memory leak.
I'd suggest calling the static method RegistrationBuilder.ForType
instead, which will give you a fluent builder and should let you subsequently call CreateRegistration
as you are now.
You can see some pretty good examples of how do this in our Moq integration:
var reg = RegistrationBuilder.ForType(concrete)
.As(@interface)
.CreateRegistration();
Also, I don't believe IfNotRegistered
will have any effect when used outside the context of a ContainerBuilder
. You should use the provided registrationAccessor
parameter to the registration source to look up a TypedService
to see if it has already been registered:
var isRegistered = registrationAccessor(new TypedService(@interface)).Any();