开发者

Structuremap addalltypesof constructed by a specific constructor

开发者 https://www.devze.com 2023-02-24 05:26 出处:网络
I really like StructureMap as an IOC-framework especially the convention based registration. Now I try to do the following: I want to add all types that implement a specific interface when the class h

I really like StructureMap as an IOC-framework especially the convention based registration. Now I try to do the following: I want to add all types that implement a specific interface when the class has a default (no parameters) constructor. And the types must be created using this constructor.

This is what I have untill now, which registers the correct types, but how do I specify that the default constructor should be used when creating an instance.

public class MyRegistry : Registry    
{
    public MyRegistry()
    {
        Scan(
           x =>
  开发者_运维技巧         {
               x.AssemblyContainingType<IUseCase>();
               x.Exclude(t => !HasDefaultConstructor(t));
               x.AddAllTypesOf<IUseCase>();
           });
    }
    private static bool HasDefaultConstructor(Type type)
    {
        var _constructors = type.GetConstructors();
        return _constructors.Any(c => IsDefaultConstructor(c));
    }

    private static bool IsDefaultConstructor(ConstructorInfo constructor)
    {
        return !constructor.GetParameters().Any();
    }
}


There are a few ways to force StructureMap to use a specific constructor. The simplest is to put the DefaultConstructor attribute on the constructor you want to use. Assuming you don't want to do that, you would have to create a custom RegistrationConvention.

public class UseCaseRegistrationConvention : IRegistrationConvention
{
    public void Process(Type type, Registry registry)
    {
        if (type.IsAbstract || type.IsInterface || type.IsEnum)
            return;

        var useCaseInterface = type.GetInterface("IUseCase");
        if (useCaseInterface == null) 
            return;

        var constructor = type.GetConstructors().FirstOrDefault(c => !c.GetParameters().Any());
        if (constructor != null)
        {
            registry.For(useCaseInterface).Add(c => constructor.Invoke(new object[0]));
        }
    }
}

Then use it in your Scan call:

Scan(x =>
   {
       x.AssemblyContainingType<IUseCase>();
       x.With(new UseCaseRegistrationConvention());
   });
0

精彩评论

暂无评论...
验证码 换一张
取 消