繁体   English   中英

反射实例化

[英]Reflection instantiation

我当前正在尝试创建一个通用实例工厂,该工厂将接口作为通用参数(在构造函数中强制执行),然后让您实例化的对象从所有已加载程序集中的所有类型实现该接口。

目前的实施情况如下:

public class InstantiationFactory<T>
{
    protected Type Type { get; set; }

    public InstantiationFactory()
    {
        this.Type = typeof(T);
        if (!this.Type.IsInterface)
        {
            // is there a more descriptive exception to throw?
            throw new ArgumentException(/* Crafty message */);
        }
    }

    public IEnumerable<Type> GetLoadedTypes()
    {
        // this line of code found in other stack overflow questions
        var types = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(a => a.GetTypes())
            .Where(/* lambda to identify instantiable types which implement this interface */);

        return types;
    }

    public IEnumerable<T> GetImplementations(IEnumerable<Type> types)
    {
        var implementations = types.Where(/* lambda to identify instantiable types which implement this interface */
            .Select(x => CreateInstance(x));

        return implementations;
    }

    public IEnumerable<T> GetLoadedImplementations()
    {
        var loadedTypes = GetLoadedTypes();
        var implementations = GetImplementations(loadedTypes);
        return implementations;
    }

    private T CreateInstance(Type type)
    {
        T instance = default(T);

        var constructor = type.GetConstructor(Type.EmptyTypes);
        if (/* valid to instantiate test */)
        {
            object constructed = constructor.Invoke(null);
            instance = (T)constructed;
        }

        return instance;
    }
}

对我来说,将我的CreateInstance(Type)函数实现为扩展方法似乎很有用,这样我以后可以重用它并简化工厂代码,但是我不知道如何从该扩展方法返回强类型值。

我意识到我可以返回一个对象:

public static class TypeExtensions
{
    public object CreateInstance(this Type type)
    {
        var constructor = type.GetConstructor(Type.EmptyTypes);
        return /* valid to instantiate test */ ? constructor.Invoke(null) : null;
    }
}

是否可以使用扩展方法为扩展类型的每个实例创建一个签名?

我的理想代码是这样,它避免了将调用结果CreateInstance()CreateInstance()

Type type = typeof(MyParameterlessConstructorImplementingType);
MyParameterlessConstructorImplementingType usable = type.CreateInstance();

我认为这是可能的,因为您试图获取仅在运行时才知道的类型的编译时类型信息(强类型化)。 您将不得不使用您的界面。

问题是,您不知道编译时在程序集中将包含哪些类型。 您甚至可以将变量用作程序集的名称! 程序集可以包含接口的任何实现。 因此,不可能告诉编译器创建从程序集中加载的类型的强类型实例。

也许是这样的吗? 我看不到没有强制转换或通用类型参数在内部处理强制转换的方法。 我使用类似的方法,其中有一个子类Type对象,但是在调用方中仅使用基类方法等。

public static object New( this Type type )
{
    return type.GetConstructor( Type.EmptyTypes ).Invoke( null );
}

public static T New<T>( this Type type )
{
    return (T)type.GetConstructor( Type.EmptyTypes ).Invoke( null );
}

// usage
MyParameterless usable = (MyParameterless)type.New();
MyParameterless usable 2 = type.New<MyParameterless>();

为什么不尝试在具有约束的扩展方法中利用泛型?

public static class TypeExtensions
{
    public T CreateInstance<T>(this T type) where T : Type
    {
        var constructor = type.GetConstructor(Type.EmptyTypes);
        return /* valid to instantiate test */ ? constructor.Invoke(null) : null;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM