You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SimpleInjector注入的类库构造函数中获取主程序集名称?

在类库构造函数中获取WCF主服务程序集名称的解决方案

我之前也碰到过一模一样的场景:用SimpleInjector把MySolution.MyLibrary注册到MySolution.MyService这个WCF服务里做单例,结果在类库构造函数里拿主服务程序集名称时踩了和你一样的坑。下面给你几个靠谱的解决办法:

方法一:依赖注入传递(最推荐)

既然用了DI容器,最符合设计原则的方式就是由服务端主动把主程序集信息传给类库,而不是让类库自己去“找”。

在MySolution.MyService的DI注册代码里,先拿到当前服务的程序集,再注册成实例:

// 服务端的DI注册代码
var hostAssembly = Assembly.GetExecutingAssembly();
container.RegisterInstance(hostAssembly);
container.Register<IMyLibrary, MyLibrary>(Lifestyle.Singleton);

然后修改MyLibrary的构造函数,接收这个Assembly参数:

public class MyLibrary : IMyLibrary
{
    public MyLibrary(Assembly hostAssembly)
    {
        string hostAssemblyName = hostAssembly.GetName().FullName;
        // 这里就拿到MySolution.MyService的完整程序集名称了
    }
}

这种方法完全避免了类库对宿主环境的依赖,不管以后宿主换成控制台、ASP.NET还是其他,只要注入对应的程序集就行,非常灵活。

方法二:遍历AppDomain加载的程序集

如果不想修改DI注册逻辑,可以遍历当前AppDomain里所有已加载的程序集,筛选出你要的那个:

public class MyLibrary : IMyLibrary
{
    public MyLibrary()
    {
        var hostAssembly = AppDomain.CurrentDomain.GetAssemblies()
            .FirstOrDefault(a => a.GetName().Name.Equals("MySolution.MyService", StringComparison.OrdinalIgnoreCase));
        
        if (hostAssembly != null)
        {
            string hostAssemblyName = hostAssembly.GetName().FullName;
            // 处理你的业务逻辑
        }
    }
}

这里用Name而非FullName匹配,是为了避免版本号、公钥令牌等信息变化导致匹配失败。不过这种方法有个小局限:如果环境里有同名程序集加载进来,可能会拿到错误的那个,适合你能确保只有一个MySolution.MyService程序集的场景。

为什么你之前的方法行不通?

顺便给你解释下踩坑的原因:

  • Assembly.GetExecutingAssembly():这个方法返回的是当前代码所在的程序集,也就是MySolution.MyLibrary本身,所以肯定拿不到服务程序集的名称。
  • Assembly.GetCallingAssembly():SimpleInjector创建实例时用到了动态方法生成(DynamicMethods),调用栈里的调用方变成了匿名动态程序集,自然返回的不是服务程序集。
  • Assembly.GetEntryAssembly():WCF服务是由IIS或WCF宿主进程(比如w3wp.exe)托管的,对于托管类库来说,入口程序集是宿主进程而非你的MySolution.MyService,所以返回null是正常的。

内容的提问来源于stack exchange,提问作者dstr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:30:27