标签:string async VID core await res gis tostring autowire
Autofac
Autofac.Extensions.DependencyInjection
将默认ServiceProviderFactory
指定为AutofacServiceProviderFactory
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseSerilog((hostBuilderContext, loggerConfiguration) =>
{
loggerConfiguration
.ReadFrom.Configuration(hostBuilderContext.Configuration)
.Enrich.FromLogContext()
.WriteTo.Console();
})
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
添加方法 ConfigureContainer
public void ConfigureContainer(ContainerBuilder builder)
{
// 在这里添加服务注册
builder.RegisterType<TopicService>();
}
默认情况下,Controller的参数会由容器创建,但Controller的创建是有AspNetCore框架实现的。要通过容器创建Controller,需要在Startup中配置一下:
services.Replace(
ServiceDescriptor
.Transient<IControllerActivator, ServiceBasedControllerActivator>()
);
// 或者将Controller加入到Services中,这样写上面的代码就可以省略了
services.AddControllersWithViews().AddControllersAsServices();
如果需要在Controller中使用属性注入,需要在ConfigureContainer
中添加如下代码
var controllerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
private readonly TopicService _service;
private readonly IServiceProvider _provider;
public TopicService Service { get; set; }
public TestController(TopicService service, IServiceProvider provider)
{
_service = service;
_provider = provider;
}
[HttpGet("{id}")]
public async Task<Result> GetTopics(int id)
{
// 构造函数注入
return await _service.LoadWithPosts(id);
}
[HttpGet("Get/{id}")]
public async Task<Result> GetTopics2(int id)
{
// 属性注入
return await Service.LoadWithPosts(id);
}
}
添加Nuget包:Autofac.Extras.DynamicProxy
public class TestInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("你正在调用方法 \"{0}\" 参数是 {1}... ",
invocation.Method.Name,
string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
invocation.Proceed();
Console.WriteLine("方法执行完毕,返回结果:{0}", invocation.ReturnValue);
}
}
Startup
的ConfigureContainer
方法注意:
1、拦截器注册要在使用拦截器的接口和类型之前
2、在类型中使用,仅virtual方法可以触发拦截器
builder.RegisterType<TestInterceptor>(); // 要先注册拦截器
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.AsImplementedInterfaces()
.EnableInterfaceInterceptors();
var controllerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired() // 允许属性注入
.EnableClassInterceptors(); // 允许在Controller类上使用拦截器
[Intercept(typeof(TestInterceptor))]
在接口上添加拦截器,当调用接口的方法时,都会进入拦截器
public class LogUtil : ILogUtil
{
public void Show(string message)
{
Console.WriteLine(message);
}
}
[Intercept(typeof(TestInterceptor))]
public interface ILogUtil
{
void Show(string message);
}
在Controller上使用拦截器
[Intercept(typeof(TestInterceptor))]
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
private readonly TopicService _service;
private readonly IServiceProvider _provider;
private readonly ILogUtil _log;
public TopicService Service { get; set; }
public TestController(TopicService service, IServiceProvider provider, ILogUtil log)
{
_service = service;
_provider = provider;
_log = log;
}
// 会触发拦截器
[HttpGet("{id}")]
public virtual async Task<Result> GetTopics(int id)
{
// 构造函数注入
return await _service.LoadWithPosts(id);
}
// 不会触发拦截器
[HttpGet("Get/{id}")]
public async Task<Result> GetTopics2(int id)
{
return await Service.LoadWithPosts(id);
}
// 会由_log触发拦截器
[HttpGet("Get2")]
public string GetTopics3()
{
_log.Show("abc");
return "Hello World";
}
// 会触发拦截器2次
[HttpGet("Get2")]
public virtual string GetTopics4()
{
_log.Show("abc");
return "Hello World";
}
}
标签:string async VID core await res gis tostring autowire
原文地址:https://www.cnblogs.com/diwu0510/p/11562248.html