Autofac系列注册
Posted mantishell
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Autofac系列注册相关的知识,希望对你有一定的参考价值。
一、注册概念
我们通过创建ContainerBuilder来注册组件并告诉容器哪些组件暴露了哪些服务。
组件可以通过反射(注册指定的.net类或开发结构的泛型)创建;通过提供现成的实例(你已创建的一个对象实例)创建,或者通过lambda表达式(一个执行实例化对象的匿名方法)来创建ContainerBuilder包含一组Register()方法来帮你实现以上操作。
每个组件暴露一个或多个服务,它们使用ContainerBuilder上的As()方法连接起来。
// Create the builder with which components/services are registered. var builder = new ContainerBuilder(); // Register types that expose interfaces... builder.RegisterType<ConsoleLogger>().As<ILogger>(); // Register instances of objects you create... var output = new StringWriter(); builder.RegisterInstance(output).As<TextWriter>(); // Register expressions that execute to create objects... builder.Register(c => new ConfigReader("mysection")).As<IConfigReader>(); // Build the container to finalize registrations // and prepare for object resolution. var container = builder.Build(); // Now you can resolve services using Autofac. For example, // this line will execute the lambda expression registered // to the IConfigReader service. using(var scope = container.BeginLifetimeScope()) { var reader = scope.Resolve<IConfigReader>(); }
1、反射组件
1.1、通过类型注册
通过反射生成的组件通常是由类型注册的。
var builder = new ContainerBuilder(); builder.RegisterType<ConsoleLogger>(); builder.RegisterType(typeof(ConfigReader));
当使用基于反射的组件时,Autofac自动为你的类从容器中寻找匹配拥有最多参数的构造方法。
假如,你有三个构造函数的类
public class MyComponent { public MyComponent() { /* ... */ } public MyComponent(ILogger logger) { /* ... */ } public MyComponent(ILogger logger, IConfigReader reader) { /* ... */ } }
现在在你的容器中注册组件和服务
var builder = new ContainerBuilder(); builder.RegisterType<MyComponent>(); builder.RegisterType<ConsoleLogger>().As<ILogger>(); var container = builder.Build(); using(var scope = container.BeginLifetimeScope()) { var component = scope.Resolve<MyComponent>(); }
当你解析组件时,Autofac发现ILogger已被注册,但你并没有注册IConfigReader,在这种情况下,第二个构造方法会被选中因为它是能在容器中找到最多参数的那个。
基于反射的组件有个重要的需要注意的地方:任何通过RegisterType 注册的组件必须是具体的类型,虽然组件可以暴漏抽象类和接口作为服务,但你不能注册一个抽象类/接口组件,你这样想就明白了:在幕后Autofac其实是创建了一个你注册对象的实例,你 无法‘new up"一个抽象类或一个接口,你得有个具体的实现,对吧。
1.2、指定构造函数
你可以使用UsingConstructor方法和构造方法中一系列代表参数类型的类型来手动指定一个构造函数,通过这种方式使用和覆盖注册组件自动选择的构造函数:
builder.RegisterType<MyComponent>() .UsingConstructor(typeof(ILogger), typeof(IConfigReader));
要注意的是,在解析时你仍然需要提供必要的参数,否则在你尝试解析对象时将出现错误,你可以在注册时传参或在解析时传递参。
1.3、实例组件
有时候,你也许会希望提前生成一个对象的实例并将它加入容器以提供注册组件时使用,你可以通过使用RegisterInstance方法:
var output = new StringWriter(); builder.RegisterInstance(output).As<TextWriter>();
当你这样做时你需要考虑一些事情,Autofac自动处理已注册组件的释放,你也许想自己来控制生命周期而不是让Autofac来帮你调用Dispose释放对象。在这种情况下,你需要通过ExternalOwned方法来注册实例:
var output = new StringWriter(); builder.RegisterInstance(output) .As<TextWriter>() .ExternallyOwned();
当将autofac集成到一个现有的应用程序(已存在一个单例实例且需要在容器中被组件使用)时,注册已提供的实例组件同样非常方便,而不是直接把这些组件绑定到单例实例上,它可以在容器中注册为一个实例:
builder.RegisterInstance(MySingleton.Instance).ExternallyOwned();
这样能确保静态单例最终能被容器管理取而代之。
通过某一实例暴露的默认服务是该实例的实体类。详见“服务vs组件”。
1.4、Lambda表达式组件
以上是关于Autofac系列注册的主要内容,如果未能解决你的问题,请参考以下文章