[Solution] 使用Autofac在MVC、Web API、WCF中实现IOC

本来想聊一下面试过程的,1个星期面了6家,4家当场给offer,2家技术通过(1家没下文,1家复试).从中也学习到一些东西,先还是继续Coding吧.

 

官网:http://autofac.org/

下载:Install-Package Autofac -Version 3.5.2

 

Autofac是轻量级的开源IOC容器,传说是速度最快的一个,同类的框架还有用过Castle Windsor、StructureMap、Unity、Spring.Net等.

 

本节目录

 

Hello World

1.建立项目

CA:一个控制台项目,引用Nuget Autofac包.

 

2.建立一个依赖外部的类

1
2
3
4
5
6
7
public class Test
{
    public Test(string str)
    {
        Console.WriteLine("hello " + str);
    }
}

 

3.根据参数名直接注入

1
2
3
4
5
6
7
8
9
10
11
static void Main(string[] args)
{<br>  //创建容器工厂
    var builder = new ContainerBuilder();
   //注册Test类型到工厂中        
    builder.RegisterType<Test>();<br>  //通过工厂创建容器
    using (var container = builder.Build())
    {<br>    //解析Test并返回Test实例
       container.Resolve<Test>(new NamedParameter("str", "world"));
    }
    Console.ReadKey();
}

 

过程:首先需要创建容器工厂,然后将各种类型注册到工厂中,再创建容器,通过容器实例化对象.

 

注入高级对象

添加1个构造函数

1
2
3
4
public Test(ISay say)
{
    Console.WriteLine("say:" + say.Get());
}

 

接口及其实现

1
2
3
4
5
6
7
8
9
10
11
12
public class Say : ISay
{
    public string Get()
    {
        return "hello world";
    }
}
 
public interface ISay
{
    string Get();
}

 

注入实现(Autofac会自动装配)

1
2
3
4
5
6
7
8
9
10
11
12
static void Main(string[] args)
{
    var builder = new ContainerBuilder();
 
    builder.RegisterType<Test>();
    builder.RegisterType<Say>().As<ISay>();
    using (var container = builder.Build())
    {
        container.Resolve<Test>();
    }
    Console.ReadKey();
}

 

略作修改

1
2
3
4
public Test(Say say)//将接口改为指定具体实现类
   {
       Console.WriteLine("say:" + say.Get());
   }

 

此时运行代码会报错,因为在容器中我们只注册了ISay接口.改为As<Say>或以下方式

1
builder.RegisterType<Say>().As<ISay>().AsSelf();

 

 

对象生命周期

注册到工厂的类型默认都调用InstancePerDependency方法.实现每个依赖都创建1个新实例

单例模式:

1
builder.RegisterType<Test>().SingleInstance();

 

 

读取配置文件注入

需要引用Nuget Autofac.Configuration包

注册类型代码

1
builder.RegisterModule(new ConfigurationSettingsReader("autofac"));

 

App.config

1
2
3
4
5
6
7
8
9
<configSections>
  <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration" />
</configSections>
<autofac defaultAssembly="CA">
  <components>
    <component type="CA.Say, CA" service="CA.ISay" />
    <component type="CA.Say, CA" service="CA.Say" />
  </components>
</autofac>

service相当于As<T>中的T

 

 

 

 

结合ASP.NET MVC

1.Install-Package Autofac.Mvc5

2.Application_Start事件添加此方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
protected void Application_Start(object sender, EventArgs e)
{
    #region 1.MVC Autofac注入
    var builder = new ContainerBuilder();
    //类名.EndsWith("Controller")
    builder.RegisterControllers(Assembly.GetExecutingAssembly());
    //这样既支持接口 又支持自己的类型
    builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
        .AsImplementedInterfaces().AsSelf();
    //容器
    var container = builder.Build();
    //注入改为Autofac注入
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    #endregion
 
    #region 2.注册MVC路由
    var routes = RouteTable.Routes;
    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
    #endregion
}

3.带参数的控制器构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class HomeController : Controller
{
    public HomeController(Say say)
    {
         
    }
    public string Index()
    {
        return "Hello World";
    }
}
 
public class Say
{
    public string Get()
    {
        return "Hello World";
    }
}

4.浏览器访问~/

 

 

结合ASP.NET Web API

1.Install-Package Autofac.WebApi

2.由于WebAPI需要,引用系统自带Web.Http和Web.Http.WebHost

3.Application_Start添加此方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void Application_Start(object sender, EventArgs e)
{
    var configuration = GlobalConfiguration.Configuration;
    #region Autofac WebAPI注入
    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces().AsSelf();
    var container = builder.Build();
    configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
    #endregion
 
    #region 注册Web API路由
    configuration.Routes.MapHttpRoute(
             name: "DefaultApi",
             routeTemplate: "api/{controller}/{id}",
             defaults: new { id = RouteParameter.Optional });
    #endregion
}

4.带参数的控制器构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ValuesController : ApiController
{
    public ValuesController(Say say)
    {
         
    }
    public string Get()
    {
        return "Hello World";
    }
}
 
public class Say
{
    public string Get()
    {
        return "Hello World";
    }
}

5.浏览器访问~/api/values

 

 

结合WCF

1.Install-Package Autofac.Wcf

2.Application_Start添加此方法

1
2
3
4
5
6
7
8
9
10
protected void Application_Start(object sender, EventArgs e)
{
    #region WCF Autofac注入
    var builder = new ContainerBuilder();
    builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces().AsSelf();
    var container = builder.Build();
    //WCF IOC容器
    AutofacHostFactory.Container = container;
    #endregion
}

 

3.新建svc服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class TestService : ITestService
{
    public TestService(Say say)
    {
 
    }
    public string DoWork()
    {
        return "Hello World";
    }
}
 
public class Say
{
    public string Get()
    {
        return "Hello World";
    }
}
 
[ServiceContract]
public interface ITestService
{
    [OperationContract]
    string DoWork();
}

 

4.svc指令中加一句:

Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf" 

 

5.wcftestclient

 

惭愧,好久没发博客了

 

posted @   Never、C  阅读(5488)  评论(7编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示