一直在寻找一个相当简单的问题的答案(我推测)。
刚开始使用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键退出
显然,我没有正确引用程序集/命名空间,并尝试了几种不同的排列来启动事情,但无济于事。文档不是很有帮助所以我在这里。
感谢您的任何意见。
答案 0 :(得分:2)
defaultAssembly
应该是要从中注册类型的程序集的名称。我看到MyInterfaces
,DefaultAdapter
和ExtraAdapter
,但您有ContainerPlugInPattern
。由于您要从两个不同的程序集中注册类型,请选择其中一个。
如果您从一个程序集中注册了大量类型,defaultAssembly
的目的就是缩短XML。每个组件type
值应该是默认程序集中类型的简单名称空间限定名称,或者它必须是完整程序集限定类型名称( http://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx和http://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>