繁体   English   中英

如何将通用存储库(或业务逻辑层)注入 ViewModel

[英]How to Inject Generic Repository(Or Business Logic Layer) Into ViewModel

为简单起见,我想将通用存储库注入到视图 model 中。 我将 ViewModel 和 Repository 添加到服务集合中,ViewModel 依赖于 Repository。 根据我的阅读,应该自动解析 ViewModel 的构造函数参数,因为它使用的是 IConfiguration。 我已经尝试在Services中显式实例化 ViewModel ,但仍然得到相同的运行时错误,并且似乎违背了我正在创建存储库的另一个实例的目的。

存储库/IRepository 看起来像这样

    public class Repository<TPoco, TDatabaseConnection> : IRepository<TPoco, TDatabaseConnection>
            where TPoco : class
            where TDatabaseConnection : IDbConnection, new()
    {

        public Repository(IConfiguration configuration, string connectionName = "DefaultConnection" )//SqlConnectionConfiguration configuration) //(string connectionString)
        {
            _connectionString = configuration.GetConnectionString(connectionName);
            _configuration = configuration;
        }


...

查看 Model

    public class PersonViewModel
    {
        private IRepository<Person, IDbConnection> _PersonRepository;

        public List<Person> Persons { get; set; }

        public PersonViewModel(IRepository<Person, IDbConnection> personRepository)
        {
            _PersonRepository=personRepository;
        }
...

在 Startup.cs 文件中,我添加如下服务:

    services.AddScoped<IRepository<Person, SQLiteConnection>, Repository<Person, SQLiteConnection>>();
    services.AddScoped<PersonViewModel>();  //runtime errors here

我收到两个运行时错误( System.AggregateException


Inner Exception 1:
InvalidOperationException: Error while validating the service descriptor 'ServiceType: BlazorInjection.ViewModels.PersonViewModel Lifetime: Scoped ImplementationType: BlazorInjection.ViewModels.PersonViewModel': Unable to resolve service for type 'DapperRepository.IRepository`2[BlazorInjection.Models.Person,System.Data.IDbConnection]' while attempting to activate 'BlazorInjection.ViewModels.PersonViewModel'.

Inner Exception 2:
InvalidOperationException: Unable to resolve service for type 'DapperRepository.IRepository`2[BlazorInjection.Models.Person,System.Data.IDbConnection]' while attempting to activate 'BlazorInjection.ViewModels.PersonViewModel'.

我错过了一个概念吗? 我该如何纠正?

将 class 结构更改为:

public class PersonViewModel
{
    private IRepository<Person> _PersonRepository;

    public List<Person> Persons { get; set; }

    public PersonViewModel(IRepository<Person> personRepository)
    {
        _PersonRepository = personRepository;
    }
}

public interface IDbConnection
{

}

public class Person { }


public interface IRepository<TPoco> { }

public class SQLiteConnection : IDbConnection 
{
    private string _connectionString;
    private IConfiguration _configuration;

    public SQLiteConnection(IConfiguration configuration, string connectionStringName)
    {
        _connectionString = configuration.GetConnectionString(connectionStringName);
        _configuration = configuration;
    }
}

public class Repository<TPoco> : IRepository<TPoco>
    where TPoco : class
{
    public IDbConnection Connection { get; }

    public Repository(IDbConnection connection)
    {
        Connection = connection;
    }
}

而不是在Startup.cs中只需更改为

services.AddScoped<IDbConnection>(sp => ActivatorUtilities.CreateInstance<SQLiteConnection>(sp, "defaultConnectionStringName"));
        services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
        services.AddScoped<PersonViewModel>();

注意通用存储库注册,它可以轻松扩展数据层。 ActivatorUtilities允许您将当前的 scope container服务与自定义参数相结合。 从设计的角度来看,我认为这种方式(一个通用的注入连接)也更好,因为您的存储库客户端不需要知道底层数据库实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM