基本上我有一个类库,其中包含了我编写的各种应用程序的大量“工具包”,然后通常引用此类库,然后创建一个空白的winforms应用程序并更改program.cs以创建工具包的实例需要。我想要做的是创建一个单独的exe,可以运行所有工具包取决于参数或设置xml文件(这一点不是问题)问题是从一个字符串不同的库创建一个类的实例。我要问的是,这可能吗?到目前为止我尝试了什么:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Advent.GlobalSettings.TestEnvironment = false;
string namespaceName = "GlobalLib.Toolkits.XmlService.Main";
//first attempt
Assembly ass = Assembly.GetExecutingAssembly();
Type CAType = ass.GetType(namespaceName);
var myObj = Activator.CreateInstance(CAType);
Form nextForm2 = (Form)myObj;
//second attempt
var t = Assembly
.GetExecutingAssembly()
.GetReferencedAssemblies()
.Select(x => Assembly.Load(x))
.SelectMany(x => x.GetTypes()).First(x => x.FullName == namespaceName);
var myObj2 = Activator.CreateInstance(t);
Application.Run((Form) myObj2);
}
首次尝试在Value cannot be null.
返回var myObj = Activator.CreateInstance(CAType);
第二次尝试返回Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
答案 0 :(得分:1)
Assembly.GetType
的{{3}}有一条说明:
要搜索其他程序集的类型,请使用Type.GetType(String)方法重载,该方法可以选择包含程序集显示名称作为类型名称的一部分。
由于您尝试加载的类型位于不同的程序集中,因此您应按照此处的建议切换到Type.GetType(String)
。您还需要调整namespaceName
变量以包含
"namespace.class, assemblyname"
您的代码需要是这样的:
//I've had a stab in the dark at your assembly name
//the bit after the comma could be wrong
string namespaceName = "GlobalLib.Toolkits.XmlService.Main, GlobalLib.Toolkits";
Type CAType = Type.GetType(namespaceName);
var myObj = Activator.CreateInstance(CAType);
Form nextForm2 = (Form)myObj;
答案 1 :(得分:1)
听起来像经典的依赖注入问题。但是,如果要跳过依赖项注入容器开销,则可能模仿行为MEF具有的行为,即来自文件夹的引用。在我看来,去GetReferencedAssemblies()
是一个坏主意,因为它也会搜索所有引用的.NET程序集,System,System.Windows.Forms等......
string companyFolder = @"<folder with assemblies>";
string fullClassName= @"<desired form fully qualified type name>";
var di = new DirectoryInfo(companyFolder);
// include forms in form apps too
var referenceAssemblyFiles = di.GetFiles("*.dll").Union(di.GetFiles("*.exe"));
var types = referenceAssemblyFiles
.Select(x => Assembly.LoadFile(x.FullName))
.SelectMany(x => x.GetTypes())
.ToList();
// might also check respective type is a form
var t = types.FirstOrDefault(x => x.FullName == fullClassName);
object myFormObj = null;
if (t != null)
{
myFormObj = Activator.CreateInstance(t);
Application.Run((Form)myFormObj);
}