如何将通用存储库(或业务逻辑层)注入视图模型



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

Repository/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;
}

...

视图模型
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'.

我错过了一个概念吗?我如何纠正这个问题?

改变类结构为:

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允许您将当前范围container服务与自定义参数结合起来。在我看来,从设计的角度来看,这种方式(一个通用的注入连接)也更好,因为您的存储库客户端不需要知道底层数据库实现。

最新更新