背景

使用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.测试效果:

请求:

结果:

最新文章

  1. Linux 信号详解一(signal函数)
  2. centos 查看是32位还是64位
  3. [LeetCode] Min Stack
  4. Expression&lt;Func&lt;T,TResult&gt;&gt;和Func&lt;T,TResult&gt;
  5. 六 mybatis高级映射(一对一,一对多,多对多)
  6. 20145305 《Java程序设计》实验四
  7. (二). 细说Kalman滤波:The Kalman Filter
  8. Jquery 工具类函数
  9. Unix/Linux环境C编程新手教程(41) C语言库函数的文件操作具体解释
  10. c++class 内存布局
  11. 用keychain这个特点来保存设备唯一标识。
  12. IOS10.3上传照片只能拍照不能选择解决办法
  13. ansible-plabybook 常用的有用的命令
  14. 网络编程基础【day10】:我是一个进程(三)
  15. 节流(Throttling)和去抖(Debouncing)详解
  16. 【第一部分】10Leetcode刷题
  17. Java生成多数值二元运算结果集
  18. leetcode-algorithms-34 Find First and Last Position of Element in Sorted Array
  19. 数据库操作API 或万能的双下划线
  20. springboot日志框架

热门文章

  1. python assert 断言详细用法格式
  2. python 将一个列表乱序
  3. python 字典添加元素
  4. log模块和report模块
  5. HDU-4511-ac自动机+dp
  6. EBS 定义并发参数常用值集
  7. 编译安装zabbix3.2.5
  8. PostgreSQL常用插件收集
  9. 配置java环境变量,实现一条命令自由切java7 或java8
  10. Javascript中的prototype与继承