Configuration 从Autofac配置访问外部类

Configuration 从Autofac配置访问外部类,configuration,autofac,Configuration,Autofac,我一直在寻找一个相当简单的问题的答案(我猜) 从Autofac和DI开始,我有4个项目的解决方案。 控制台应用程序看起来像: namespace ContainerPlugInPattern { class Program { static void Main(string[] args) { try { // Option1: Fill container with

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

从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();
        }
    }
}
<?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>
namespace ContainerPlugInPattern
{
班级计划
{
静态void Main(字符串[]参数)
{
尝试
{
//选项1:用已知对象填充容器
//var builder=new ContainerBuilder();
////配置-可以通过编程方式或通过配置完成,
////使用泛型强类型,或使用类型更动态,
////可以指示每个解析创建的实例是单实例还是新实例
//builder.RegisterType().As();
//builder.RegisterType().As();
//builder.RegisterType().As();
//var container=builder.Build();
//选项2:从配置的组件填充容器
//var builder=new ContainerBuilder();
//builder.RegisterModule(新配置设置阅读器(“autofac”);
//builder.RegisterType().As();
//var container=builder.Build();
//消费者代码
var adapters=container.Resolve();
foreach(适配器中的var适配器)
{
adapter.Configure(“foo”);
适配器.Connect();
}
}
捕获(例外情况除外)
{
WriteLine(“异常:{0}”,例如Message);
}
控制台。写线(“”);
控制台写入线(“按回车键退出”);
Console.ReadLine();
}
}
}
然后是一个具有IInstrumentAdapter和IMessageHandler的库(MyInterfaces.DLL和Namespace=MyInterfaces)

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

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

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

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

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();
        }
    }
}
<?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>

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

例外:类型“DefaultAdapters.Adapter1,ContainerPlugInPattern.DefaultAdap” 找不到ters。可能需要装配鉴定,例如“MyType,M 亚塞姆利”

按回车键退出

显然,我没有正确地引用程序集/名称空间,并尝试了几种不同的排列来启动程序,但没有成功。文档不是很有用,所以我在这里


感谢您的输入。

默认程序集应该是要从中注册类型的程序集的名称。我看到了
MyInterfaces
DefaultAdapter
extracadapter
,但您在其中有
ContainerPlugInPattern
。由于您正在注册来自两个不同程序集的类型,请选择其中一个

defaultAssembly
的要点是,如果要从一个程序集中注册大量类型,则要缩短XML。每个组件
type
值都应该是默认程序集中类型的简单命名空间限定名,或者它需要是完整的程序集限定类型名(and)


符合条件的程序集是
Namespace.Type,程序集
like
ContainerPlugInPattern.DefaultAdapters.Adapter1,DefaultAdapters
。您所拥有的似乎是类型和名称空间的组合。切换到程序集限定类型名称,您应该可以开始了。(如果您切换了,但仍不起作用,请使用新代码更新您的问题,以便我们可以看到您尝试了什么。)

这就是配置现在的样子

<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>

谢谢!这就是我需要的推动,配置现在看起来像这样,一切都按预期工作。