在mvc中使用依赖项注入

本文关键字:依赖 注入 mvc | 更新日期: 2023-09-27 18:04:03

在我们的一个应用程序中,我已经在使用AppTenant类的依赖注入,如下所示

public void ConfigureServices(IServiceCollection services)
{
services.AddMultitenancy<AppTenant, CachingAppTenantResolver>();
services.Configure<MultitenancyOptions>(Configuration.GetSection("Multitenancy"));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
 app.UseMultitenancy<AppTenant>();
}

在控制器中,我可以很容易地访问它,如下

public AccountController(AppTenant tenant)
    {
        this.tenant = tenant;
    }

现在,我想访问同一解决方案中其他项目类中的相同AppTenantHttpContext。所以,我试过这样的

public SqlStringLocalizerFactory(
       AppTenant tenant)
    {
     _tenant = tenant;
    }

但是它是空的,所以我需要做什么,在另一个项目类中获得AppTenantHttpContext

对于SqlStringLocalizerFactory类,服务是用ConfigureServices方法编写的,如下所示

public static class SqlLocalizationServiceCollectionExtensions
{
    public static IServiceCollection AddSqlLocalization(this IServiceCollection services)
    {
        if (services == null)
        {
            throw new ArgumentNullException(nameof(services));
        }
        return AddSqlLocalization(services, setupAction: null);
    }
   public static IServiceCollection AddSqlLocalization(
        this IServiceCollection services,
       Action<SqlLocalizationOptions> setupAction)
    {
            if (services == null)
        {
            throw new ArgumentNullException(nameof(services));
        }
        services.TryAdd(new ServiceDescriptor(
            typeof(IStringExtendedLocalizerFactory),
            typeof(SqlStringLocalizerFactory),
            ServiceLifetime.Singleton));
        services.TryAdd(new ServiceDescriptor(
            typeof(IStringLocalizerFactory),
            typeof(SqlStringLocalizerFactory),
            ServiceLifetime.Singleton));
        services.TryAdd(new ServiceDescriptor(
            typeof(IStringLocalizer),
            typeof(SqlStringLocalizer),
            ServiceLifetime.Singleton));
        if (setupAction != null)
        {
            services.Configure(setupAction);
        }
        return services;
    }
}

我甚至尝试过IHttpContextAccessor,但仍然没有成功。

感谢您在这方面的帮助!

在mvc中使用依赖项注入

第2版

新解决方案:

public SqlStringLocalizerFactory(IHttpContextAccessor _accessor)
{
   _accessor= accessor;
}
public void SomeMethod()
{
    var tenant = _accessor.HttpContext.RequestServices
            .GetRequiredService<AppTenant>();
}

编辑IServiceProvider方式并不像我预期的那样工作。查看@Sock的解决方案

首先,我假设问题的出现是因为@cujck指出的捕获依赖关系。避免捕获依赖:

如果SqlStringLocalizerFactory的生存期必须是singleton(在某些情况下必须是(案例使用IServiceProvider:

public SqlStringLocalizerFactory(IServiceProvider serviceProvider)
{
   _serviceProvider = serviceProvider;
}
public void SomeMethod()
{
    var tenant =  _serviceProvider.GetService<AppTenant>();
}

否则,对于您的情况,使用AddScoped似乎是合理的。

您有两个选项,最好的选项是,如果SqlStringLocalizerFactory可以是作用域依赖项(您为每个请求都获得一个新实例(,那么您可以将其注册为作用域依赖:

services.TryAdd(new ServiceDescriptor(
        typeof(IStringLocalizerFactory),
        typeof(SqlStringLocalizerFactory),
        ServiceLifetime.Scoped));

如果SqlStringLocalizerFactory必须是Singleton依赖项,那么您需要确保通过使用ServiceSope:来解决租户的作用域依赖项

public class SqlStringLocalizerFactory
{
    private readonly IServiceProvider _serviceProvider;
    public SqlStringLocalizerFactory(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }
    public void SomeMethod()
    {
        using (var serviceScope = _serviceProvider
            .GetRequiredService<IServiceScopeFactory>().CreateScope())
        {
            var tenant = serviceScope.ServiceProvider.GetService<AppTenant>();
            // do something with tenant...
        }
    }
}