背景

使用Autofac进行依赖注入时,经常遇到的场景是在容器中进行类似如下代码的注入操作:

builder.RegisterType<BackInStockSubscriptionService>().As<IBackInStockSubscriptionService>().InstancePerLifetimeScope();
builder.RegisterType<CategoryService>().As<ICategoryService>().InstancePerLifetimeScope();
builder.RegisterType<CompareProductsService>().As<ICompareProductsService>().InstancePerLifetimeScope();
builder.RegisterType<RecentlyViewedProductsService>().As<IRecentlyViewedProductsService>().InstancePerLifetimeScope();
builder.RegisterType<ManufacturerService>().As<IManufacturerService>().InstancePerLifetimeScope();
builder.RegisterType<PriceFormatter>().As<IPriceFormatter>().InstancePerLifetimeScope();
builder.RegisterType<ProductAttributeFormatter>().As<IProductAttributeFormatter>().InstancePerLifetimeScope();
builder.RegisterType<ProductAttributeParser>().As<IProductAttributeParser>().InstancePerLifetimeScope();

因为这种注入是统一进行的,随着项目规模的扩大和代码复杂度的增加,需要在注册的地方不断地增加新的类来注册类型,这样会使代码失去了开闭原则:对修改关闭,对扩展开放。

解决方案

1. 定义一个属性用于标识类的注入意图,在应用初始化时利用反射进行集中类型注册。

    public class InjectableAttribute : Attribute
{ }

2. 在需要注入的类型中,使用[Injectable]标记注入

 public class Employee
{
public string Name { get; set; } public string Password { get; set; }
} public interface IEmployeeManager
{
IList<Employee> GetAllEmployess();
} public interface IEmployeeRepository
{
IList<Employee> GetAllEmployess();
} [Injectable]
public class EmployeeRepository : IEmployeeRepository
{
public IList<Employee> GetAllEmployess()
{
List<Employee> list = new List<Employee>();
list.Add(new Employee { Name = "a", Password = "b" });
return list;
}
} [Injectable]
public class EmployeeManager : IEmployeeManager
{
private readonly IEmployeeRepository _employeeRepository; public EmployeeManager(IEmployeeRepository employeeRepository)
{
_employeeRepository = employeeRepository;
} public IList<Employee> GetAllEmployess()
{
var employeeData = _employeeRepository.GetAllEmployess();
var employeeList = new List<Employee>();
foreach (var employee in employeeData)
{
var employ = new Employee();
employ.Password= employee.Password;
employ.Name = employee.Name;
employeeList.Add(employ);
}
return employeeList;
}
}

3. 在WebApi的Controller中进行注入操作

 public class EmployeeController : ApiController
{
private readonly IEmployeeManager _employeeManager; public EmployeeController(IEmployeeManager employeeManager)
{
_employeeManager = employeeManager;
} [AllowAnonymous]
[ResponseType(typeof(Employee))]
public IHttpActionResult GetEmployees()
{
var employeeData = _employeeManager.GetAllEmployess();
return Ok(employeeData);
}
}

4. 项目中引用 Autofac.WebApi2 and AutoFac,定义如下容器初始化类

 public static class AutofacDependecyBuilder
{
public static void DependencyBuilder()
{
// Create the builder with which components/services are registered.
var builder = new ContainerBuilder(); // Register your Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.Where(t
=> t.GetCustomAttribute<InjectableAttribute>() != null)
.AsImplementedInterfaces()
.InstancePerRequest();
builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration); //Build the Container
var container = builder.Build(); //Create the Dependency Resolver
AutofacWebApiDependencyResolver resolver = new AutofacWebApiDependencyResolver(container); //Configuring WebApi with Dependency Resolver
GlobalConfiguration.Configuration.DependencyResolver =
resolver; } }

5. 在Web程序开始处调用容器注册

    public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes); AutofacDependecyBuilder.DependencyBuilder();
}
}

6.测试效果:

请求:

结果:

Autofac容器使用属性进行WebApi自动注入的更多相关文章

  1. Spring容器是如何实现 Bean 自动注入(xml)

    入口web.xml web.xml 配置文件 <!-- Spring Config --> <listener> <listener-class>org.sprin ...

  2. Servlet自动注入Spring容器中的Bean解决方法

    很多情况在进行Web开发的时候需要自己手写Servlet来完成某些功能,而servlet有需要注入Spring容器中的某些bean,这是每次都要手动获取比较麻烦,这里有一个解决方案,只需要写一个ser ...

  3. Istio技术与实践03:最佳实践之sidecar自动注入

    Istio通过对serviceMesh中的每个pod注入sidecar,来实现无侵入式的服务治理能力.其中,sidecar的注入是其能力实现的重要一环(本文主要介绍在kubernetes集群中的注入方 ...

  4. Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入

    首先看下Demo2的结构     然后下面一步步将Autofac集成到mvc中. 首先,定义Model Product.cs public class Product { public int Id ...

  5. .NET领域最为流行的IOC框架之一Autofac WebAPI2使用Autofac实现IOC属性注入完美解决方案 AutoFac容器初步

    .NET领域最为流行的IOC框架之一Autofac   一.前言 Autofac是.NET领域最为流行的IOC框架之一,微软的Orchad开源程序使用的就是Autofac,Nopcommerce开源程 ...

  6. 自己实现简单的AOP(五)使Demo适应webApi、亦可完成属性自动注入

    在前文的Demo中,webApi的Controller是不能自动注入的,原因是 IHttpController 和 IController 是通过两个不同的途径进行激活的. IHttpControll ...

  7. DotNetCore跨平台~autofac属性的自动注入

    回到目录 在使用autofac这个DI工具时,我们一般使用的是构造方法注入,而dotnetcore的标准框架里也集成了构造方法注入,而属性注入在一些场景下,表现的更为灵活,像java的spring框架 ...

  8. .NET MVC5+ EF+AutoFac自动注入框架

    1.创建一个MVC系统 VIEW显示页面代码: <link href="~/Content/bootstrap.css" rel="stylesheet" ...

  9. .NET MVC5+ Dapper+扩展+AutoFac自动注入实现

    1.首先创建一个MVC项目 定义Model 层  view 层 index.cshtml  控制器层Controllers等文件 2.在线安装或者引用dapper 以及扩展相关包 同时Autofac ...

随机推荐

  1. JS localStorage 存储变量

    if(!window.localStorage && /MSIE/.test(navigator.userAgent)){ if(!window.UserData) { window. ...

  2. python 哈希查找

    import random INDEXBOX= #哈希表元素个数 MAXNUM= #数据个数 class Node: #声明链表结构 def __init__(self,val): self.val= ...

  3. JAVA消息 AMQP

    AMQP(Advanced Message Queuing Protocol)高级的消息队列

  4. 关于keyCode, 键盘代码。 和零散的javascript知识。http://js2.coffee/(转化工具)

    这个是coffeescript代码 document.addEventListener 'turbolinks:load', ->   document.getElementById(" ...

  5. js 文件系统API操作示例

    最近有个需求是:自动抓取某网站登录页面的验证码图片并保存,抓取n次.使用chrome插件来实现,其中使用到了js操作文件系统的api,特将代码记录下来,以备查阅. PS:第一次使用js文件系统的api ...

  6. poj-2096-期望/dp

    http://poj.org/problem?id=2096 有n种病毒,s个服务器,每天等概率的在某个服务器上发现某一种病毒,问发现所有种类病毒且覆盖所有的服务器的期望天数. 利用全期望公式可以将期 ...

  7. C#读写配置文件Config

    应用程序配置文件是标准的XML文件,XML标记和属性是区分大小写的.它是可以按需要更改的,开发人员可以使用配置文件来更改设置,而不必重编译应用程序.配置文件的根节点是configuration.我们经 ...

  8. 【LeetCode 222_完全二叉树_遍历】Count Complete Tree Nodes

    解法一:递归 int countNodes(TreeNode* root) { if (root == NULL) ; TreeNode *pLeft = root->left; TreeNod ...

  9. ubuntu14.04安装Android Studio出现error while loading shared libraries: libz.so.1的解决方法

    参考博客地址: http://blog.csdn.net/newairzhang/article/details/28656693 安装lib32z1就可以解决,如下: 首先,sudo apt-get ...

  10. websocket 缺点

    当时用 python 做的服务器,后来回去想再工作项目上用,但新的技术升级,随之而来还是要解决很多非技术问题, 服务器带宽,并发服务器性能方方面面考虑之后还是没有用上,十分可惜, 一个新的技术推动,尤 ...