问题
I used following statement to decorate all my ICommandHandlers<>
with Decorator1<>
:
ObjectFactory.Configure(x =>
{
x.For(typeof(ICommandHandler<>)).DecorateAllWith(typeof(Decorator1<>));
});
But because Decorator1<>
implements ICommandHandlers<>
, the Decorator1<>
class decorates itself too.
So, the problem is that the Decorator1
registers inadvertently, when I register all the ICommandHandler<>
's.
How can I filter DecorateWithAll()
to decorate all ICommandHandler<>
, except Decorator1<>
?
回答1:
ObjectFactory is obsolete.
You can exclude Decorator1<>
from being registered as a vanilla ICommandHandler<>
with code like this:
var container = new Container(config =>
{
config.Scan(scanner =>
{
scanner.AssemblyContainingType(typeof(ICommandHandler<>));
scanner.Exclude(t => t == typeof(Decorator1<>));
scanner.ConnectImplementationsToTypesClosing(typeof(ICommandHandler<>));
});
config.For(typeof(ICommandHandler<>)).DecorateAllWith(typeof(Decorator1<>));
});
UPDATE
For multiple modules you can use The Registry DSL to compose a portion of your application
using StructureMap;
using StructureMap.Configuration.DSL;
public class CommandHandlerRegistry : Registry
{
public CommandHandlerRegistry()
{
Scan(scanner =>
{
scanner.AssemblyContainingType(typeof(ICommandHandler<>));
scanner.Exclude(t => t == typeof(Decorator1<>));
scanner.ConnectImplementationsToTypesClosing(typeof(ICommandHandler<>));
});
For(typeof(ICommandHandler<>)).DecorateAllWith(typeof(Decorator1<>));
}
}
Only the Composition Root needs to be aware of all the Registry
implementations.
var container = new Container(config =>
{
config.AddRegistry<CommandHandlerRegistry>();
});
You even have the option of finding all Registry
instances at runtime (you still need to ensure all the required assemblies are loaded)
var container = new Container(config =>
{
var registries = (
from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.DefinedTypes
where typeof(Registry).IsAssignableFrom(type)
where !type.IsAbstract
where !type.Namespace.StartsWith("StructureMap")
select Activator.CreateInstance(type))
.Cast<Registry>();
foreach (var registry in registries)
{
config.AddRegistry(registry);
}
});
来源:https://stackoverflow.com/questions/30841303/define-filter-for-decorateallwith-method-in-structure-map-3