Configuration 从Autofac配置访问外部类
我一直在寻找一个相当简单的问题的答案(我猜) 从Autofac和DI开始,我有4个项目的解决方案。 控制台应用程序看起来像:Configuration 从Autofac配置访问外部类,configuration,autofac,Configuration,Autofac,我一直在寻找一个相当简单的问题的答案(我猜) 从Autofac和DI开始,我有4个项目的解决方案。 控制台应用程序看起来像: namespace ContainerPlugInPattern { class Program { static void Main(string[] args) { try { // Option1: Fill container with
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,程序集likeContainerPlugInPattern.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>
谢谢!这就是我需要的推动,配置现在看起来像这样,一切都按预期工作。