如何加载app.config中指定的程序集 [英] How to load an assembly which is specified in app.config

查看:85
本文介绍了如何加载app.config中指定的程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个控制台应用程序abc.exe。我有另一个名为abc.xyz.dll的程序集。两个应用程序都在同一个解决方案中



结构

abc

- abc

---- abc.exe

- abc.xyz

---- abc.xyz.dll



我想在控制台应用程序abc.exe中动态加载abc.xyz.exe程序集,其中app.config文件中提到了程序集的名称

 <   appSettings  >  
< add key = modelType value = abc.xyz.Worker,abc.xyz / >
< / appSettings >







我试过

  string  assembName = ConfigurationManager.AppSettings.Get(   modelType); 



 type = Type.GetType (assembName); 





但它返回null。我不想在GAC中加载程序集或在环境变量中指定路径。



请帮我解决。

< br $>


我试图解决下面的问题

开发一个控制台应用程序,它将在运行时探测给定的模型类,并要求用户填写对象。



作为我们作业的一部分,模型类是一个简单的类,如下所示:



 [Model(DisplayName =  员工)] 
public class 工人
{
[显示(姓名= 员工ID)]
public int WorkerId { get ; set ; }
[显示(名称= 全名)]
public string 名称{ get ; set ; }
[显示(名称= 出生日期)]
< span class =code-keyword> public DateTime DateOfBirth { get ; set ; }
[显示(名称= 薪水)]
public decimal 报酬{ get ; set ; }
}





创建名为DynamicConsole.Core.dll的程序集,并使用'创建属性'Model' DisplayName'属性。



o在Visual Studio中,使用代码片段属性作为推荐模式。
$ b $b创建另一个名为组织的程序集.Domain.dll',并创建模型类Worker,如上所示。



o你需要添加对'DynamicConsole.Core.dll'和'System.ComponentModel的引用.DataAnnotations.dll'解析'Model'和'Display'属性的引用。


$ b $b创建一个控制台应用程序'DynamicConsole.exe'。

o此应用程序将从app.config中选择模型类型,并要求用户填写所需的详细信息。



(key =modelType,value =FullyResolvedTypeName,AssemblyName)



o你需要什么添加对DynamicConsole.Core.dll和System.ComponentModel.DataAnnotations.dll的引用,以解析模型和显示属性的引用。



o不要添加对'Organization.Domain.dll'的引用,因为它应该在运行时从

app.config中选择。



< ; appsettings>

< add key =modelTypevalue =Organization.Domain.Worker,Organization.Domain>

解决方案

你已经得到了答案,但我不确定你的混淆是否被驳回。从您尝试的代码中可以清楚地看出,1)您甚至没有尝试加载程序集(但您之后已经了解了它); 2)你误解了集合名称和类型的功能。



没问题;很容易与这个命名混淆。你只需要仔细看看MSDN。您的 assemblyName 不是程序集名称。并且程序集名称根本不是字符串。 System.Reflection.AssemblyName 是一个更复杂的数据结构,它可以唯一地识别程序集,这对GAC很重要,并带有其他重要功能: https://msdn.microsoft.com/en-us/library/system。 reflection.assemblyname%28v = vs.110%29.aspx [ ^ ]。



如果使用其名称加载程序集,在实践中,它只来自GAC。您的配置文件中可能有一些文件名。这是您需要理解的另一件事:文件不是程序集,即使它是表示程序集的唯一工件。该文件始终是一个模块,一个模块可能有也可能没有程序集清单。默认情况下,Visual Studio始终创建单模块程序集,但在较低级别上,您始终可以创建由多个模块组成的程序集;在这种情况下,这些模块中只有一个具有程序集清单。它的文件名是你必须使用的名称,比如 Assembly.LoadFrom 。它与程序集名称无关。



另请参阅:

https://msdn.microsoft.com/en-us/library/7d3c18c2%28v=vs.110%29.aspx [ ^ ],

https://msdn.microsoft.com/en-us/library/system.reflection.assembly.getname%28v=vs.110%29.aspx [ ^ ]。br />


另一个困惑是:你需要理解 System.Type 。首先, System.Type.GetType(string)需要类型名称,它与程序集名称无关,与模块文件名无关。它只能在已加载程序集时用于某些程序集类型: https ://msdn.microsoft.com/en-us/library/w3f99sx1(v = vs.110).aspx [ ^ ]。



这是人们可能做的最糟糕的事情。通过动态加载程序集,您可以构建类似插件系统的东西,其中动态加载的程序集是一种插件。但是如何使用加载的组件? GetType 的问题是:并且缺少给定名称下的类型是什么?更糟糕的是,如果它在主机应用程序中拼写错误怎么办?



不,这不是很好维护。与此同时,至少有一种坚如磐石的方法。您可以定义主机和动态加载的程序集都知道的某个接口,通过动态加载的程序集中的某些类型实现它 - 这将很容易识别而不使用任何字符串。您可以采取一些措施使其成为非常有效的机制。请参阅我过去的答案以获取更多详细信息:

动态加载用户控件 [ ^ ],

C#Reflection InvokeMember on现有实例 [ ^ ],

通过它的字符串表示从集合中收集类型 [ ^ ],

一般来说插件的用途是什么 [ ^ ],

以编程方式添加引用 [ ^ ],

a摘要引用其他答案可以在这里找到:访问驻留在插件dll中的自定义对象 [ ^ ]。



-SA


请参阅此MSDN页面如何:将程序集加载到应用程序域 [ ^ ]



[更新]

你也可以使用加载和程序集的长名称,请参阅 Assembly.Load方法(字符串) [ ^ ]

I am developing a console application abc.exe. I have another assembly called abc.xyz.dll. Both the applications are in same solution

Structure
abc
--abc
----abc.exe
--abc.xyz
----abc.xyz.dll

I want to dynamically load the abc.xyz.exe assembly in the console application abc.exe where the name of assembly is mentioned in app.config file

<appSettings>
    <add key="modelType" value="abc.xyz.Worker,abc.xyz" />    
  </appSettings>




I have tried

string assembName = ConfigurationManager.AppSettings.Get("modelType");


type = Type.GetType(assembName);



but it returns null. I do not want to load the assembly in GAC or specify the path in environment variable.

Please help me with a solution.


I am trying to solve below problem
Develop a console application which would probe a given model class at runtime, and ask the user to fill the object.

The model class, as part of our assignment, is a simple class as shown below:

[Model(DisplayName = "Employee")]
public class Worker
{
[Display(Name = "Employee ID")]
public int WorkerId { get; set; }
[Display(Name = "Full Name")]
public string Name { get; set; }
[Display(Name = "Date of Birth")]
public DateTime DateOfBirth { get; set; }
[Display(Name = "Salary")]
public decimal Remuneration { get; set; }
}



Create an assembly named ‘DynamicConsole.Core.dll’, and create an attribute ‘Model’ with ‘DisplayName’ property.

o In Visual Studio, use code snippet ‘attribute’ for the recommended pattern.
 Create another assembly named ‘Organization.Domain.dll’, and create model class Worker as shown above.

o You would need to add references to ‘DynamicConsole.Core.dll’ and ‘System.ComponentModel.DataAnnotations.dll’ to resolve references of ‘Model’ and ‘Display’ attributes.

 Create a console application ‘DynamicConsole.exe’.
o This application will pick the model type from app.config, and ask the user to fill in the required details.

(key="modelType", value="FullyResolvedTypeName, AssemblyName")

o You would need to add references to ‘DynamicConsole.Core.dll’ and ‘System.ComponentModel.DataAnnotations.dll’ to resolve references of ‘Model’ and ‘Display’ attributes.

o Don’t add reference to ‘Organization.Domain.dll’ as it should be picked from
app.config during runtime.

<appsettings>
<add key="modelType" value="Organization.Domain.Worker, Organization.Domain">

解决方案

You already got an answer, but I'm not sure that you confusion is dismissed. From the code you attempted, it's clear that 1) you did not even try to load an assembly (but you already learned about it later); 2) you misunderstand assembly name and the function of the type.

No problem; it's easy to be confused with this naming. You just need to take a closer look at MSDN. Your assemblyName is not an assembly name. And assembly name is not a string at all. System.Reflection.AssemblyName is a more complicated data structure, it can identify the assembly uniquely, which is important for GAC, and carry other important function: https://msdn.microsoft.com/en-us/library/system.reflection.assemblyname%28v=vs.110%29.aspx[^].

If you load assembly using its name, in practice, it's only from GAC. You probably have some file name in your config file. Here is another thing you need to understand: the file is not the assembly, even when it is the only artifact representing an assembly. The file is always a module, and a module may or may not have assembly manifest. By default, Visual Studio always create single-module assemblies, but on lower level you can always create an assembly made of more than 1 module; in this case, only one of these modules will have an assembly manifest. And its file name is the name you have to use in, say, Assembly.LoadFrom. It has nothing to do with assembly name.

See also:
https://msdn.microsoft.com/en-us/library/7d3c18c2%28v=vs.110%29.aspx[^],
https://msdn.microsoft.com/en-us/library/system.reflection.assembly.getname%28v=vs.110%29.aspx[^].

Another confusion is: you need to understand System.Type. First of all, System.Type.GetType(string) expects type name, which has nothing to do with assembly name and nothing to do with a module file name. It can only be used on some assembly types when an assembly is already loaded: https://msdn.microsoft.com/en-us/library/w3f99sx1(v=vs.110).aspx[^].

And this is a worst thing one can possibly do. With dynamic loading of assemblies, you are building something like a plug-in system, where a dynamically loaded assembly is a kind of plug-in. But how to use the loaded assembly? The problem with GetType is: and what is the type under a given name is absent? Worse, what if it is misspelled in the host application?

No, this is not well maintainable. At the same time, there is at least one rock-solid approach. You could define some interface known to both host and dynamically loaded assembly, implement it by some of the types in the dynamically loaded assembly — that will it easily recognizable without using any strings. You can do some steps to make it very efficient mechanism. Please see my past answers for further detail:
Dynamically Load User Controls[^],
C# Reflection InvokeMember on existing instance[^],
Gathering types from assemblies by it's string representation[^],
What is the use of plugin in general[^],
adding reference programmatically[^],
a summary referencing other answers can be found here: Access a custom object that resides in plug in dll[^].

—SA


Refer to this MSDN page How to: Load Assemblies into an Application Domain[^]

[UPDATE]
You can also use Load and the long name of the assembly, see Assembly.Load Method (String)[^]


这篇关于如何加载app.config中指定的程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆