Define filter for DecorateAllWith() method in structure-map 3

纵然是瞬间 提交于 2019-12-10 17:36:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!