猿问

Autofac:如何在 SingleInstance 范围内使用每个请求依赖项?

有IDbConnection注册为per-request和ApplicationOAuthProvider注册为 的连接依赖项single instance。


builder.Register(c => new SqlConnection(WebConfigUtils.DefaultConnectionString))

            .As<IDbConnection>()

            .InstancePerRequest();


builder.RegisterType<ApplicationOAuthProvider>()

            .As<IOAuthAuthorizationServerProvider>()

            .PropertiesAutowired()

            .SingleInstance();

需要在身份声明中存储用户权限。为此,我创建了命令 GetRolePermissions,在此命令中我想注入IDbConnection实例。


public class GetRolePermissions

{

    public class Command: IRequest<List<string>>

    {

        public ICollection<AspNetUserRole> UserRoles { get; set; }

    }


    public class Handler : AsyncRequestHandler<Command, List<string>>

    {

        private IDbConnection databaseConnection;


        public Handler(IDbConnection databaseConnection)

        {

            this.databaseConnection = databaseConnection;

        }

    }

}

正在创建此命令 ApplicationOAuthProvider


public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider

{

    private async Task<ClaimsIdentity> GenerateUserIdentityAsync(AspNetUser user, string authenticationType)

    {

        user.SecurityStamp = Guid.NewGuid().ToString();

        var identity = await mediator.Send(new GenerateUserIdentity.Command

        {

            AuthenticationType = authenticationType,

            User = user

        });

    }

}

permissions = await mediator.Send(new GetRolePermissions.Command { UserRoles = user.Roles });-GetRolePermissions.Handler需要注入时抛出错误IDbConnection,但当前的 autofac 范围ApplicationOAuthProvider是"root"并且没有iDbConnection在此范围内注册。但它存在于per-request范围内。


不想perLifettime用于 IDbConnection,因为我认为,dbConnection在不必要时应该关闭它。我想这样做:


using(var scope = AutofacConfig.container.BeginLifiTime("AutofacWebRequest")) 

{

      permissions = await mediator.Send(new GetRolePermissions.Command { UserRoles = user.Roles });

}

但无法使此解决方案起作用。而且我不知道如何正确获取容器,现在它是我手动设置的 AutofacConfig 的静态变量。


如何启用的注入IDbConnection到这个GetPermissions.Handler?


ibeautiful
浏览 130回答 1
1回答

慕婉清6462132

实际上,InstancePerLifetimeScope()就是您要寻找的解决方案。您需要做的就是注入 DbConnection工厂,该工厂生成DbConnection 的拥有(docs link 1和docs link 2)实例,而不是 DbConnection 本身。// registrationbuilder.RegisterType<SqlConnection>()&nbsp; &nbsp; .As<IDbConnection>()&nbsp; &nbsp; .WithParameter(new NamedParameter("connectionString", WebConfigUtils.DefaultConnectionString))&nbsp; &nbsp; .InstancePerLifetimeScope();// usagepublic class GetRolePermissions{&nbsp; &nbsp; public class Command: IRequest<List<string>>&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; public ICollection<AspNetUserRole> UserRoles { get; set; }&nbsp; &nbsp; }&nbsp; &nbsp; public class Handler : AsyncRequestHandler<Command, List<string>>&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; private Func<Owned<IDbConnection>> _connectionFactory;&nbsp; &nbsp; &nbsp; &nbsp; public Handler(Func<Owned<IDbConnection>> connectionFactory)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _connectionFactory = connectionFactory;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // not really sure where your consuming code is, so just something off the top of my head&nbsp; &nbsp; &nbsp; &nbsp; public DontKnowYourResultType Handle(GetRolePermissions.Command cmd) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; using (var ownedConnection = _connectionFactory()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ownedConnection.Value is the DbConnection you want&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ... do your stuff with that connection&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } // and connection gets destroyed upon leaving "using" scope&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}它确实改变了作为请求作用域的子作用域的行为,但我不确定这是否是您的代码的问题 - 试一试,它应该可以正常工作。如果没有,那么你知道去哪里问。;)
随时随地看视频慕课网APP
我要回答