autofac 注册

1 注册的概念和方式

使用autofac 的ContainerBuilder 来注册组件(components---通常指实现类),并把它的服务(service---通常指接口,抽象类,类实例)暴露给调用方。

autofac 通过相似的 Register() 方法来进行注册,通过As() 方法来公开服务

1) 创建一个ContainerBuilder 来注册组件和服务

 var builder = new ContainerBuilder();

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

2)  通过反射类型来进行注册 。

builder.RegisterType<ConsoleLogger>.As<ILogger>();

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

3)  通过一个实例来进行注册

var output = new StringWriter();
builder.RegisterInstance(output).As<TextWriter>();

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

4) 通过Lamda表达式的方式来构建注册

// Register expressions that execute to create objects...
builder.Register(c => new ConfigReader("mysection")).As<IConfigReader>();

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

5) 通过RegisterGeneric()方法 支持泛型接口注册

//注册
builder.RegisterGeneric(typeof(List<>))
       .As(typeof(IList<>))
       .InstancePerLifetimeScope();
//解析代码
var tasks = container.Resolve<IList<String>>();

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

容器会自动根据传递的 T 类型 进行解析

6) 通过程序集进行注册

// 通过程序集进行注册
   builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上代码AsImplementedInterfaces() 方法 会把当前运行的程序集中所有实现了接口的组件进行注册,并把接口作为服务对外公开。

例如: 程序集中包含了 2个接口:IOutput 和 IDateWriter

和三个实现类:class ConsoleOutput : IOutput

class CurentDateWriter :IDateWriter

class MyComponent:IOutput,IDateWriter

那么这三个都会被注册。如果程序集中还有其他类型实现了接口,也会被自动注册,除了 IDisposable 接口。

7) 通过链式语法把一个组件注册为多个服务对外公开

// 链式注册
builder.RegisterType<MyComponent>()
       .AsSelf()    // 公开MyComponent 的实例
       .As<IOutput>()   // 公开IOutput 的 实例
       .As<IDataWriter>();    // 公开 IDataWriter 的实例

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

所以如下三种解析都可以正常工作

// 都可以正常执行
scope.Resolve<IOutput>();
scope.Resolve<IDataWriter>();
scope.Resolve<MyComponent>();

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

2  条件注册

1) 注册时添加筛选条件

示例1:在程序集中,通过Where() 筛选名称以“Repository” 结尾的类进行注册,并制定服务进行公开

// asm 为一个程序集变量
builder.RegisterAssemblyTypes(asm)
       .Where(t => t.Name.EndsWith("Repository"))
       .As<IRepository>();

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

通过Where 提供Lamda 集合操作,可以对类进行筛选。

示例2 : 通过 Except() 方法排除不需要注册的类

//  排除 MyUnwantedType 不注册
builder.RegisterAssemblyTypes(asm)
       .Except<MyUnwantedType>();

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

3  Autofac 自动解析规则

1)  当组件类有多个构造函数,通过RegisterType 方法注册的组件后,解析服务时,会通过反射形式,根据构造函数参数从多到少的方式匹配。

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

// 多构造函数组件
 public class MyComponent
    {
        public string Name {get;set;}
        public MyComponent() { Name = "no parameter"; }
        public MyComponent(IOutput output) { Name = string.Format("parameter is {0}", output.ToString()); }
        public MyComponent(IOutput output, IDateWriter writer) { Name = string.Format("parameter is {0} and {1}", output.ToString(),writer.ToString()); }
    }

 class Program
    {
        static IContainer container { get; set; }
        static void Main(string[] args)
        {
            var builder = new ContainerBuilder();

            // 注册类型,通过反射注册
            builder.RegisterType<MyComponent>();
            builder.RegisterType<ConsoleOutput>().As<IOutput>();

            container = builder.Build();  //构建容器

            //使用
            using (var scope = container.BeginLifetimeScope())
            {
                var component = container.Resolve<MyComponent>();
                Console.WriteLine(component.GetType());
                Console.WriteLine(component.Name);
            }           

            Console.ReadKey();
        }
    }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

  • Autofac 根据上诉代码,在解析MyComponent 时,会先看容器中,是否有已注册的 ILoger 和IConfigReader 的 服务
  • Autofac 发现只有一个ILoger 服务,而没有 IConfigReader 的服务,于是自动选择 带一个ILoger 构造参数的 构造函数实例化 M

运行结果:

2) 通过UsingConstructor()指定构造函数注册

builder.RegisterType<MyComponent>()
       .UsingConstructor(typeof(ILogger), typeof(IDataWriter));

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

  • 当容器中,存在ILoger 和IDataWriter  的 注册时,当Resolve<MyComponent> 时,容器会返回2个构造函数的实例
  • 当容器中,只存在Iloger  的注册时,因为是手动用2个构造函数进行祖册,此时Resolve<MyComponent> 会抛出异常,因为IDataWriter 的注册实例不存在。
时间: 2024-07-28 13:53:49

autofac 注册的相关文章

Autofac 使用经验

慢慢总结 基础使用样例,在 Application_Start 中直接使用 //autofac注册 var builder = new ContainerBuilder(); //注册Controller方式一 自己指定程序集 //var assemblies = new List<Assembly> { Assembly.Load("TestEf.Web") }; //builder.RegisterControllers(assemblies.ToArray()); /

.NET手记-Autofac进阶Registering Components

通过创建ContainerBuilder并配置暴露的service(接口或者类型)来使用Autofac注册我们的组件. 组件(Components) 可以通过反射, 提供对象实例化,或者通过lambda表达式来创建. ContainerBuilder有一系列的Register()方法来实现组件的注册. ContainerBuilder中每个组件都能通过As()方法来暴露他们一个或多个service. // Create the builder with which components/serv

多层架构+MVC+EF+AUTOFAC+AUTOMAPPER【转】

多层架构+MVC+EF+AUTOFAC+AUTOMAPPER 最近使用ligerui搭建了一个简单的教务管理demo,将重要的地方记录,也希望能帮到有这方面需要园友. 一.目录 1.多层架构+MVC+EF+AUTOFAC+AUTOMAPPER: 2.MVC中验证码的实现(经常用,记录备用) 二.正文 多层架构中等以上规模以上的系统用得比较多,此demo功能不多,出于抱着学习的态度搭建了一个多层架构,并加入现在很流行的依赖倒转(autofac).对象映射工具(automapper). 话说没图你说

IoC实践--用Autofac实现MVC5.0的IoC控制反转方法

Autofac是一个.net平台下发性能还不错的IoC框架,利用它可以实现依赖注入和控制反转,使自己的软件模块之间的耦合性大大降低,让软件扩展.维护更加容易.控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题.下面我就用Autofac实现ASP.NET mvc5.0的IOC控制反转的方法.这里用到是vs2013,Autofac ASP.NET MVC 5 Integration和mvc 5.0.Autofac ASP.N

多层架构+MVC+EF+AUTOFAC+AUTOMAPPER

最近使用ligerui搭建了一个简单的教务管理demo,将重要的地方记录,也希望能帮到有这方面需要园友. 一.目录 1.多层架构+MVC+EF+AUTOFAC+AUTOMAPPER: 2.MVC中验证码的实现(经常用,记录备用) 二.正文 多层架构中等以上规模以上的系统用得比较多,此demo功能不多,出于抱着学习的态度搭建了一个多层架构,并加入现在很流行的依赖倒转(autofac).对象映射工具(automapper). 话说没图你说个J8,先上框架图: Model层中Entity存放数据库实体

asp.net mvc4 简单使用Autofac依赖注入小结

1,首先使用 NuGet下载适当的Autofac版本 文件一,Autofac.3.5.2 文件二,Autofac.Mvc4.3.1.0 1,接口类 public interface IRepository { void GetListCount(); } 2,实现类 public class Repository:IRepository { public void GetListCount() { //return 1; } } 3,控制器 public class HomeController

.net core2.1 三层中使用Autofac代替原来Ioc

首先,现有的三层项目的结构 其中  Repository public interface IPersonRepository { string Eat(); } public class PersonRepository : IPersonRepository { public string Eat() { return "吃饭"; } } Service public interface IPersonService { string Eat(); } public class P

net core 3 使用 autofac

参考官方:https://docs.autofac.org/en/latest/integration/aspnetcore.html#startup-class 有一些变动,现在暂时还没用net core3 做项目 public class Program { public static void Main(string[] args) { // ASP.NET Core 3.0+: // The UseServiceProviderFactory call attaches the // A

netcore使用AutoFac实现AOP

原文:netcore使用AutoFac实现AOP 第一步,添加程序集引用 在Nuget中搜索autofac找到Autofac.Extras.DynamicProxy并安装. 第二步:添加拦截器 /// <summary> /// 拦截器(实现 Castle.DynamicProxy.IInterceptor)接口 /// </summary> public class CustomAutoFacAOPInterception : IInterceptor { public void