汇编中的Autofac寄存器类型

时间:2018-08-09 21:52:49

标签: c# .net autofac

我在解决方案中使用了autofac来解决不同项目之间的库依赖关系。从某种意义上说,创建热插拔库的想法是,应用程序仅依赖几个核心库,它们以"vmecore.*.dll"为前缀。必须在其他任何库之前向autofac注册。

加载任何其他以“ vme。*。dll为前缀”的库,然后寻找实现“ IVmeExtension”的第一个类型-它定义了 Initiate()方法-注册它,激活它,最后对其进行初始化。

注册核心库的代码:

        Directory.GetFiles(path, "vmecore.*.dll")
            .Select(Assembly.LoadFile)
            .ToList()
            .ForEach(ass =>
            {
                //var validAss = Assembly.Load(ass.FullName);

                builder.RegisterAssemblyTypes(ass)
                    .Where(t => t.IsAssignableTo<IVmeExtension>())
                    .SingleInstance();
                //return;

                // Iterate through all the types in the assembly
                foreach (var type in ass.GetExportedTypes()
                        .Where(a => a.IsClass &&
                                    !a.IsAbstract &&
                                    a.Namespace != null &&
                                    a.Namespace.Contains(@"VME")))
                {
                    // Get the first type of IVmeExtension
                    if (!typeof(IVmeExtension).IsAssignableFrom(type)) continue;

                    //builder.RegisterType(type).SingleInstance();
                    coreExtension.Add(type);
                    break;
                }
            });

下面的代码片段是在构建容器时调用的回调委托。核心库需要在热插拔扩展之前进行解析和初始化,因为大多数扩展都依赖于它们。

           //Register a call back when container is built so we can resolve core extensions first
            builder.RegisterBuildCallback(container =>
            {
                coreExtension.ForEach(ext =>
                {
                    try
                    {
                        var inst = (IVmeExtension)container.Resolve(ext);
                        inst.Initiate();

                        Interface.LogInfo($"VME: Core extension '{inst.Name}'");
                    }
                    catch (Exception e)
                    {
                        // we log the error here.
                        throw;
                    }
                });
            });

已解决的第二个扩展名需要将前一个注入到构造函数中-对于本实验,我在构造函数中手动解析了它,以查看注册的服务-。问题出现在这里;我看到“请求的服务'..'尚未注册”的异常,但在查看注册时,那里的类型是文学的。

Screenshot

我已经尝试了这篇帖子https://github.com/autofac/Autofac/issues/593上的解决方案建议,但是当我这样做时,我得到了系统指针异常,并且自从进入实例(var inst = (IVmeExtension)container.Resolve(ext))实例的激活以来,它就非常清楚了。实际上带我去了一个完全不同的类的构造函数-该不同的类在执行的程序集中-

1 个答案:

答案 0 :(得分:0)

经过一段时间的挖掘,我简化了将文件加载到其中的过程:

  array =  new Proxy(array, {
    get(target, prop, receiver) {
      if(!isNaN(+prop)) --prop;
      return Reflect.get(target, prop, receiver);
    },
    set(target, prop, value) {
      if(!isNaN(+prop)) --prop;
      return Reflect.set(target, prop, value);
    },
  });

我的原始版本无法正常工作的原因是,即使文件程序集已加载,也没有加载到应用程序域中,所以当我注册一个类型时,它将得到一个哈希代码-autofac使用-。当应用尝试解析类型时,这时会将程序集加载到应用域中。在这一点上,所有新加载的类型都有不同的哈希码-我以为这就是发生的情况-导致了我描述的错误。

奇怪的是,我提到的无效指针异常实际上是在激活第二个扩展并解析其依赖关系时实际上导致的-以正确的方式,其中一个打开了一个tcp套接字,该套接字的IP地址输入有误(uurghh同事ehh)

有时候,简单的代码就是更好的代码:)