简体   繁体   English

反射实例化

[英]Reflection instantiation

I am currently trying to create a generic instance factory for which takes an interface as the generic parameter (enforced in the constructor) and then lets you get instantiated objects which implement that interface from all types in all loaded assemblies. 我当前正在尝试创建一个通用实例工厂,该工厂将接口作为通用参数(在构造函数中强制执行),然后让您实例化的对象从所有已加载程序集中的所有类型实现该接口。

The current implementation is as follows: 目前的实施情况如下:

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

It seems useful to me to have my CreateInstance(Type) function implemented as an extension method so I can reuse it later and simplify the code of my factory, but I can't figure out how to return a strongly typed value from that extension method. 对我来说,将我的CreateInstance(Type)函数实现为扩展方法似乎很有用,这样我以后可以重用它并简化工厂代码,但是我不知道如何从该扩展方法返回强类型值。

I realize I could just return an object: 我意识到我可以返回一个对象:

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

Is it possible to have an extension method create a signature per instance of the type it extends? 是否可以使用扩展方法为扩展类型的每个实例创建一个签名?

My perfect code would be this, which avoids having to cast the result of the call to CreateInstance() : 我的理想代码是这样,它避免了将调用结果CreateInstance()CreateInstance()

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

I don' think it is possible, because you are trying to get compile time type information (strongly typing) of types you only know at runtime . 我认为这是可能的,因为您试图获取仅在运行时才知道的类型的编译时类型信息(强类型化)。 You will have to work with your interfaces. 您将不得不使用您的界面。

The problem is, you don't know which types will be contained in your assemblies at compile tim. 问题是,您不知道编译时在程序集中将包含哪些类型。 You could even use a variable for the name of your assembly! 您甚至可以将变量用作程序集的名称! Your assembly may contain any implementation of your interface. 程序集可以包含接口的任何实现。 So there is no possibilty to tell the compiler to create a strongly typed instance of the type you load from your assembly. 因此,不可能告诉编译器创建从程序集中加载的类型的强类型实例。

Maybe something like this? 也许是这样的吗? I don't see a way without a cast or a generic type param to handle the cast internally. 我看不到没有强制转换或通用类型参数在内部处理强制转换的方法。 I use something similar to this where I have a subclass Type object coming in, but use only base class methods etc. in the caller. 我使用类似的方法,其中有一个子类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>();

Why not try utilizing generics in your Extension method with constraints? 为什么不尝试在具有约束的扩展方法中利用泛型?

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