从Autofac配置访问外部类

时间:2014-08-08 16:02:30

标签: configuration autofac

一直在寻找一个相当简单的问题的答案(我推测)。

刚开始使用Autofac和DI,所以我有一个包含4个项目的解决方案。 控制台应用程序看起来像:

namespace ContainerPlugInPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // Option1: Fill container with known objects
                //var builder = new ContainerBuilder();
                //// configuration - can be done programmatically or through configuration, 
                //// strongly typed with generics or more dynamically with Types, 
                //// can indicate whether created instances should be singleton or new instance per resolve
                //builder.RegisterType<Adapter1>().As<IInstrumentAdapter>();
                //builder.RegisterType<ExtraAdapter>().As<IInstrumentAdapter>();
                //builder.RegisterType<MessageHandler>().As<IMessageHandler>();
                //var container = builder.Build();

                // Option2: fill container from configured components
                //var builder = new ContainerBuilder();
                //builder.RegisterModule(new ConfigurationSettingsReader("autofac"));
                //builder.RegisterType<MessageHandler>().As<IMessageHandler>();
                //var container = builder.Build();

                // Consumer code
                var adapters = container.Resolve<IEnumerable<IInstrumentAdapter>>();
                foreach (var adapter in adapters)
                {
                    adapter.Configure("foo");
                    adapter.Connect();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception:{0}", ex.Message);
            }

            Console.WriteLine("");
            Console.WriteLine("Hit enter to exit");
            Console.ReadLine();
        }
    }
}

然后是一个具有IInstrumentAdapter和IMessageHandler的库(MyInterfaces.DLL和Namespace = MyInterfaces)。

然后是另一个库(DefaultAdapters.DLL和Namespace = ContainerPlugInPattern.DefaultAdapters),它有一个实现IInstrumentAdapter的类

最后是第三个库(ExtraAdapter.DLL和Namespace = ContainerPlugInPattern.ExtraAdapters),它有一个也实现了IInstrumentAdapter的类。

主应用程序引用了所有库,如果我在try块的顶部执行Option1代码,我会得到控制台反馈,所有对象都已创建并按预期运行。我在这里遇到的问题是主应用程序必须使这些引用正常工作(即我不能单独发布这些模块或随着时间的推移扩展其他库)。

我真正想要的是通过XML配置加载这些组件,并使这些组件存在于不同的程序集和命名空间中,而不需要在主应用程序中引用它们。所以我的配置文件如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
      <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration" />
    </configSections>

    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
    </startup>


    <autofac defaultAssembly="ContainerPlugInPattern">
        <components>
          <component 
            type="DefaultAdapters.Adapter1, ContainerPlugInPattern.DefaultAdapters"
            service="MyInterfaces.IInstrumentAdapter" />
          <component
            type="ExtraAdapter.ExtraAdapter, ContainerPlugInPattern.ExtraAdapter"
          service="MyInterfaces.IInstrumentAdapter" />
        </components>
    </autofac>

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

当我尝试使用配置文件运行应用程序时,我得到以下异常:

异常:类型&#39; DefaultAdapters.Adapter1,ContainerPlugInPattern.DefaultAdap TER值&#39;无法找到。它可能需要装配认证,例如&#34; MyType,M yAssembly&#34;

按Enter键退出

显然,我没有正确引用程序集/命名空间,并尝试了几种不同的排列来启动事情,但无济于事。文档不是很有帮助所以我在这里。

感谢您的任何意见。

2 个答案:

答案 0 :(得分:2)

defaultAssembly应该是要从中注册类型的程序集的名称。我看到MyInterfacesDefaultAdapterExtraAdapter,但您有ContainerPlugInPattern。由于您要从两个不同的程序集中注册类型,请选择其中一个。

如果您从一个程序集中注册了大量类型,defaultAssembly的目的就是缩短XML。每个组件type值应该是默认程序集中类型的简单名称空间限定名称,或者它必须是完整程序集限定类型名称http://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspxhttp://msdn.microsoft.com/en-us/library/yfsftwz6(v=vs.110).aspx)。

装配限定为Namespace.Type, Assembly,如ContainerPlugInPattern.DefaultAdapters.Adapter1, DefaultAdapters。你所拥有的似乎是那里的类型和命名空间的组合。切换到程序集限定类型名称,你应该很高兴。 (如果您切换它仍然无法正常工作,请使用新代码更新您的问题,以便我们查看您尝试过的内容。)

答案 1 :(得分:0)

这就是配置现在的样子

<autofac defaultAssembly="DefaultAdapters">
    <components>
      <component 
        type="ContainerPlugInPattern.DefaultAdapters.Adapter1, DefaultAdapters"
        service="MyInterfaces.IInstrumentAdapter, MyInterfaces" />
      <component
        type="ContainerPlugInPattern.ExtraAdapters.ExtraAdapter, ExtraAdapter"
      service="MyInterfaces.IInstrumentAdapter, MyInterfaces" />
    </components>
</autofac>