本文介绍了Structuremap addalltypesof 由特定构造函数构造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的很喜欢 StructureMap 作为 IOC 框架,尤其是基于约定的注册.现在我尝试执行以下操作:当类具有默认(无参数)构造函数时,我想添加实现特定接口的所有类型.并且必须使用此构造函数创建类型.

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();
    }
}

推荐答案

有几种方法可以强制 StructureMap 使用特定的构造函数.最简单的方法是将 DefaultConstructor 属性放在您要使用的构造函数上.假设您不想这样做,则必须创建自定义 RegistrationConvention.

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());
   });

这篇关于Structuremap addalltypesof 由特定构造函数构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 14:23