StructureMap: How to set lifecycle on types connected with ConnectImplementationsToTypesClosing
In my registry I have
Scan(scanner =>开发者_StackOverflow;
{
scanner.AssemblyContainingType<EmailValidation>();
scanner.ConnectImplementationsToTypesClosing(typeof(IValidation<>));
});
What am I supposed to do to define these all as Singletons?
Also as an aside to this question, is there any reason to not define everything that is stateless as a singleton object that's registered in StructureMap?
Kevin's answer is correct for versions 2.5.4 and older. In the current StructureMap trunk (and when 2.5.5+ is released), you can now do:
Scan(scanner =>
{
scanner.AssemblyContainingType<EmailValidation>();
scanner.ConnectImplementationsToTypesClosing(typeof(IValidation<>))
.OnAddedPluginTypes(t => t.Singleton());
});
The assembly scanner method ConnectImplementationsToTypesClosing uses a IRegistrationConvention to get the job done. To do this I copied and updated the StructureMap generic connection scanner to also take a scope. Next I created a handy assembly scanner extension method to use as syntactic sugar to wire it up.
public class GenericConnectionScannerWithScope : IRegistrationConvention
{
private readonly Type _openType;
private readonly InstanceScope _instanceScope;
public GenericConnectionScannerWithScope(Type openType, InstanceScope instanceScope)
{
_openType = openType;
_instanceScope = instanceScope;
if (!_openType.IsOpenGeneric())
{
throw new ApplicationException("This scanning convention can only be used with open generic types");
}
}
public void Process(Type type, Registry registry)
{
Type interfaceType = type.FindInterfaceThatCloses(_openType);
if (interfaceType != null)
{
registry.For(interfaceType).LifecycleIs(_instanceScope).Add(type);
}
}
}
public static class StructureMapConfigurationExtensions
{
public static void ConnectImplementationsToSingletonTypesClosing(this IAssemblyScanner assemblyScanner, Type openGenericType)
{
assemblyScanner.With(new GenericConnectionScannerWithScope(openGenericType, InstanceScope.Singleton));
}
}
Here is the appropriate setup code.
Scan(scanner =>
{
scanner.ConnectImplementationsToSingletonTypesClosing(typeof(IValidation<>));
});
Hope this helps.
精彩评论