本文介绍了通过反射加载类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个控制台应用程序和两个类库(A和B).我在A类中有"a"类,在B类中有"b"类.
显然,我的程序输入点将是控制台应用程序.在"a"类中,
我正在通过反射加载"b"的类型.

I have a console application and two class libraries say (A and B). I have class "a" in A and class "b" in B.
Obviously my entry poin of program will be the console application. In class "a",
I am loading the type of "b" through reflection.

Type type = null;
            type = Type.GetType(a,A, version=..,token=) //assembly qualified name;
            object obj = Activator.CreateInstance(type);



现在我的问题是,上面的代码在哪里需要B的引用才能起作用.我是否需要类库A中的类库B的引用或控制台应用程序本身,或者我根本不需要它.

为了使我的方案更加具体,我提供了示例示例.
我有一个名为TestType的类库.它具有一个名为TypeA的类.



Now my question is for the above code to work where do i need the reference of B. Do i need the reference of class library B in class library A or the console Application itself or I do not need it at all.

To make my scenario more specific, I am providing my sample example.
I have a class library named TestType. It has a single class named TypeA.

namespace TestType
{
    public class TypeA
    {
        TypeA() { }
    }
}



同样,我还有一个名为TestApp的类库,其中Runner类试图通过
创建TypeA对象.反思.



Likewise I have another class library named TestApp in which Runner class is trying to create an object of TypeA through
reflection.

namespace TestApp
{
    public static class Runner
    {
        public static void CreateInstance()
        {
            Type t = Type.GetType("TestType.TypeA, TestType, Version=1.0.0.0, Culture=neutral");
        }

    }
}




我有一个控制台应用程序来测试功能.




I have a console application to test the functionaly.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ReflectionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            TestApp.Runner.CreateInstance();
        }
    }
}



现在,当我运行此命令时,"Runner"将返回NULL.但是,当我在"ReflectionTest"中添加"TestType"的引用时,则可以正常工作.
我只想知道,为什么有必要添加反映在控制台应用程序中的类型的引用.相反,我的假设是"TestApp"需要引用"TestType",因为它是返回"TypeA"对象的对象.



Now when I run this, "Runner" returns NULL. But when I add reference of "TestType" in "ReflectionTest" then it works fine.
All I wanted to know is, why is it necessary to add the reference of type being reflected in the console application. Instead my assumption was "TestApp" would need the reference of "TestType" since it is the one which is returning the object of "TypeA".

推荐答案

object o = Activator.CreateInstance(type);
o.CallMyMethod(); // error




Type.GetType要求您提供完全限定的程序集名称,它不能与完全限定的类型名称一起使用,因此请执行以下操作:




Type.GetType requires you to supply a fully qualified assembly name, it will not work with the full qualified type name, so do the following :

string[] s = typestr.Split(new char{','},2); // typestr = "TestType.TypeA, TestType, Version=1.0.0.0, Culture=neutral"
object o = Activator.CreateInstance(s[0].Trim(), s[1].Trim());


// interface assembly I
public interface IMyPlugin
{
   string Name { get; }
   ...
}

// implementation A assembly: reference to assembly I
public class MyPluginA: IMyPlugin
{
   public string Name { get { return m_Name; } }
   ...
}

// main assembly: references only assembly I
...
Dictionary<string, IMyPlugin> m_Plugins = new Dictionary<string, IMyPlugin>();
...
foreach(Type type in LoadMyPluginConfig(...))
{
    IMyPlugin plugin = (IMyPlugin)Activator.CreateInstance(type);
    m_Plugins.Add(plugin.Name, plugin);
}
...


您可能需要看一下 MEF(托管扩展框架) [ ^ ]为您完成这种激活.

干杯
Andi


You may want to have a look at MEF (Managed Extensibility Framework)[^] to have this kind of activation done for you.

Cheers
Andi


namespace ConsoleApplication9
{
    class Program
    {
        static void Main(string[] args)
        {
            Type type = Type.GetType("LibA.ClassA, LibA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
            object obj = Activator.CreateInstance(type);
            Console.WriteLine(obj.ToString());
        }
    }
}


有关LibB的LibA:


LibA with reference to LibB:

namespace LibA
{
    public class ClassA
    {
        public ClassB Other { get; set; }
        public ClassA()
        {
            Other = new ClassB();
        }
    }
}


LibB:


LibB:

namespace LibB
{
    public class ClassB
    {
        public void Write(string message)
        {
            Console.WriteLine("Message: {0}", message);
        }
    }
}

  1. 上述步骤
  2. 将程序集手动复制到一个目录(粗体)
  3. 如果产品中有特定的部署结构,请实施程序集解析处理程序


我建议采用第一种方法,因为这是最简单的方法.否则,解析处理程序将有所帮助.


I suggest to go the 1st approach since it is the simplest one. Otherwise, a resolution handler would help.


这篇关于通过反射加载类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 04:40
查看更多