有没有办法单独从名称空间/类型字符串获取类型?

发布于 2024-09-27 03:45:50 字数 203 浏览 1 评论 0原文

我需要引用外部程序集中的类型。我知道命名空间和类型名称,并且知道程序集将位于 GAC 中,但仅此而已。有没有办法获得这种类型。我发现有一种从 GUID 或程序 ID 获取它的方法对我有用,但我知道开发外部程序集的人可能会偏离这些类似 COM 的属性。所以,我不想依赖他们。

仅作为参考,我希望我的软件在升级外部软件时能够非常通用。因此,我不能依赖于为我提供的某些版本的程序集。

I am needing to reference a type in an external assembly. I know the namespace and the type name and I know the assembly will be in the GAC, but that's it. Is there a way to get this type. I see there's a way to get it from a GUID or Program ID which works for me, but I know the people who develop the external assembly may drift away from these COM-like attributes. So, I don't want to depend on them.

Just for a frame of reference, I'd like my software to be very versatile when it comes to this external software being upgraded. So I can't depend on certain versions of assemblies being there for me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

眉黛浅 2024-10-04 03:45:50

如果程序集位于 GAC 中,则可以按名称加载程序集,然后使用迭代遍历其所有类型
Assembly.GetTypes()。您可以使用 loadpartialname 但不推荐使用它来获取没有完全限定名称的程序集。

查看 Assembly.Load()
Assembly.GetType()

You can load an assembly by name if its in the GAC and then iterate though all its types using
Assembly.GetTypes(). You can use loadpartialname but its deprecated to get an assembly with out the fully qualified name.

Look at Assembly.Load()
and Assembly.GetType()

并安 2024-10-04 03:45:50

您知道程序集名称还是不知道?
如果你知道程序集名称就很简单:

Object Creator(string assemblyname, string classname) 
{
   System.Type objType = System.Type.GetType(assemblyname + "." + classname);
   Return Activator.CreateInstance(objType);
}

Do you know the assemblyname or do you not know?
if you know the assembylname than it is easy:

Object Creator(string assemblyname, string classname) 
{
   System.Type objType = System.Type.GetType(assemblyname + "." + classname);
   Return Activator.CreateInstance(objType);
}
╰つ倒转 2024-10-04 03:45:50

由于您知道这肯定位于 GAC 中,因此您可以列出 gacutil /l 的结果。这将为您提供 GAC 中每个程序集的列表。

由此,您可以启动一个执行以下操作的循环:

foreach assemblyName in list
    Create new AppDomain
    Load assembly into new appdomain
    check for type in assembly
    if exists:
        return assemblyName to main appDomain
    Unload appdomain

在单独的 AppDomain 中执行此操作非常重要,否则您将把所有这些程序集永久加载到您的程序中。

请注意,这将非常非常慢,而且不完全是我所推荐的。一旦您知道正确的类型名称,您很可能应该将其缓存在应用程序设置中以供将来加载。


编辑:

正如 Hans 指出的那样,Gacutil 需要安装 .NET SDK 才能使用。如果这不是有效选项,您可以使用 C++/CLI 制作 .NET 可访问 API 以从 GAC 检索信息。有一个用于访问 GAC 信息的本机 API,但是这不是托管 API。

Since you know this is guaranteed to be in the GAC, you could list the results of gacutil /l. This will give you a list of every assembly in the GAC.

From that, you could start a loop that did the following:

foreach assemblyName in list
    Create new AppDomain
    Load assembly into new appdomain
    check for type in assembly
    if exists:
        return assemblyName to main appDomain
    Unload appdomain

It's important to do this in a separate AppDomain, or you'll load all of these assemblies permanently into your program.

Note that this is going to be very, very slow, and not exactly something I'd recommend. Once you know the proper type name, you should most likely cache this in your app settings for future loads.


Edit:

As Hans points out, Gacutil requires a .NET SDK installation to use. If this is not a valid option, you can use C++/CLI to make a .NET accessable API to retrieve information from the GAC. There is a Native API for accessing GAC information, but this is not a managed API.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文