我正在asp.net core 2中创建自定义路由,我在其中检查数据库中的路径并将操作和控制器更新为所需的路径。
我有像这样定义的自定义IRouter
public interface IRouteCustom : IRouter
{
}
public class RouteCustom : IRouteCustom
{
private readonly IRouter _innerRouter;
private readonly IMemoryCache _memoryCache;
private readonly IUnitOfWork _unitOfWork;
public RouteCustom(IRouter innerRouter, IMemoryCache memoryCache, IUnitOfWork unitOfWork)
{
_innerRouter = innerRouter ?? throw new ArgumentNullException(nameof(innerRouter));
_memoryCache = memoryCache;
_unitOfWork = unitOfWork;
}
public async Task RouteAsync(RouteContext context)
{
I check the routes in the DB using the _unitOfWork
}
public VirtualPathData GetVirtualPath(VirtualPathContext context)
{
Also I do the same here...
}
}
我对这些功能没有任何问题,我可以选择控制器和动作。
我的问题是如何访问数据库,因为我无法将IUnitOfWork依赖项注入到自定义路由器中。
我收到此错误消息:
'Cannot resolve 'IUnitOfWork' from root provider because it requires scoped service 'DbContext'.'
我的配置服务就像这样
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DbContext>(options => options.UseMySQL(configuration.GetConnectionString("DefaultClient")));
services.AddIdentity<Domain.EntitiesClient.Entities.ApplicationUser, Domain.EntitiesClient.Entities.ApplicationRole>().AddEntityFrameworkStores<DbContext>().AddDefaultTokenProviders();
services.AddScoped<IDbContext, DbContext>();
services.AddTransient<IUnitOfWork, UnitOfWork>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddMemoryCache();
services.AddMvc();
/*route custom*/
var supportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("es-ES"), new CultureInfo("it-IT") };
var optionsCulture = new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture("en-US", "en-US"), SupportedCultures = supportedCultures, SupportedUICultures = supportedCultures };
optionsCulture.RequestCultureProviders = new IRequestCultureProvider[] { new RouteDataRequestCultureProvider() { RouteDataStringKey = "culture", Options = optionsCulture } };
services.AddSingleton(optionsCulture);
}
配置
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.Routes.Add(new RouteCustom(routes.DefaultHandler
, routes.ServiceProvider.GetRequiredService<IMemoryCache>()
, app.ApplicationServices.GetService<IUnitOfWork>()
));
routes.MapRoute(name: "areas", template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
});
}
问题出在这里
app.ApplicationServices.GetService<IUnitOfWork>()
我需要注入IUnitOfWork以检查数据库,但我不知道该怎么做。在其他中间件中,我可以直接在函数中注入IUnitOfWork,但在这种情况下我无法在
中执行此操作public async Task RouteAsync(RouteContext context)
我怎样才能做到这一点?我确定我在这里做错了,但我一直在阅读很多文章而且无法弄明白。
感谢。
更新:可能的解决方案
我能想到的唯一解决方案是将注入删除到IRouter并在RouteAsync方法中“手动”获取服务。
public async Task RouteAsync(RouteContext context)
{
var unitOfWork = context.HttpContext.RequestServices.GetRequiredService<IUnitOfWork>()
var routes = unitOfWork.Router.GetAll();
...
}
这样我们就可以访问数据库并且运行良好。 这是一个好方法吗?