在.net core中使用Autofac依赖注入
1.创建AutofacModuleRegister类
servicesDllFile,repositoryDllFile是需要注入的类库,
如builder.RegisterAssemblyTypes(assemblysServices),就是配置servicesDllFile路径的类库的注入
public class AutofacModuleRegister : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
var basePath = AppContext.BaseDirectory;
#region 带有接口层的服务注入
var servicesDllFile = Path.Combine(“”);
var repositoryDllFile = Path.Combine(basePath, AppSettingsConstVars.Dal);
if (!(File.Exists(servicesDllFile) && File.Exists(repositoryDllFile)))
{
var msg = "Repository.dll和Services.dll 丢失,因为项目解耦了,所以需要先F6编译,再F5运行,请检查 bin 文件夹,并拷贝。";
throw new Exception(msg);
}
builder.RegisterType<Context>().As<DbContext>()
.AsImplementedInterfaces()
.InstancePerDependency()
.PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
builder.RegisterType<RequestInterception>();
// 获取 Service.dll 程序集服务,并注册
var assemblysServices = Assembly.LoadFrom(servicesDllFile);
//支持属性注入依赖重复
builder.RegisterAssemblyTypes(assemblysServices)
.AsImplementedInterfaces()
.InstancePerDependency()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(RequestInterception))
.PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
// 获取 Repository.dll 程序集服务,并注册
var assemblysRepository = Assembly.LoadFrom(repositoryDllFile);
//支持属性注入依赖重复
builder.RegisterAssemblyTypes(assemblysRepository)
.AsImplementedInterfaces()
.InstancePerDependency()
//.EnableInterfaceInterceptors()
//.InterceptedBy(aops.ToArray())//服务层的拦截器加一个即可 多个会造成重复拦截报错
.PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
#endregion
}
}
2.配置Startup
在ConfigureServices和Configure新建ConfigureContainer
由于.net core 是管道模型运行,所以ConfigureContainer会在ConfigureServices之后运行,在Configure之前运行
这个代码的含义是,在项目启动时会在创建ControllerBase子类,并且不是ControllerBase的控制器创建对象是开启依赖注入
public void ConfigureContainer(ContainerBuilder builder)
{
//获取所有控制器类型并使用属性注入
var controllerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
builder.RegisterModule(new AutofacModuleRegister());
}
3.基础使用
一般在配置上面设置后,在控制器中重写构造函数
如现有IUserService接口,以及他的实现UserService。
3.1通过构造函数注入
public class UserController : BaseApiController
{
private readonly IUserService service;
public UserController(IUserService service)
{
this.service = service;
}
}
3.2方法对象注入
public class UserController : BaseApiController
{
private readonly IUserService service;
public UserController()
{
this.service = AutofacUtil.GetService();
}
}其中AutofacUtil帮助方法
ILifetimeScope是Autofac内部对象,这个需要在Startup类的Configure方法中初始化
AutofacUtil.Container = app.ApplicationServices.GetAutofacRoot();public class AutofacUtil
{
public static ILifetimeScope Container { get; set; }
/// <summary>
/// 获取服务(Single)
/// </summary>
/// <typeparam name="T">接口类型</typeparam>
/// <returns></returns>
public static T GetService<T>()
{
return Container.Resolve<T>();
}
/// <summary>
/// 获取服务(请求生命周期内)
/// </summary>
/// <typeparam name="T">接口类型</typeparam>
/// <returns></returns>
public static T GetScopeService<T>() where T : class
{
return (T)GetService<IHttpContextAccessor>().HttpContext.RequestServices.GetService(typeof(T));
}
}