c# - 使用 autofac 注册泛型类型
问题描述
我试图通过遵循这个堆栈来让它工作,但它对我不起作用。我有这个模块
public class ProductsModule : Module
{
protected override void Load(ContainerBuilder builder)
{
RegisterPerDependency(builder);
RegisterPerRequest(builder);
}
private static void RegisterPerDependency(ContainerBuilder builder)
{
builder.RegisterType<DatabaseContext>().As<DbContext>().InstancePerDependency();
builder.RegisterGeneric(typeof(Service<>)).AsSelf().InstancePerDependency();
}
private static void RegisterPerRequest(ContainerBuilder builder)
{
builder.RegisterGeneric(typeof(DataProvider<>)).AsSelf().InstancePerRequest();
}
}
我有这项服务:
/// <summary>
/// Generic service for entity framework
/// </summary>
/// <typeparam name="T">An entity model</typeparam>
public class Service<T> : IService<T> where T : class
{
// Create our private properties
private readonly DbContext _context;
private readonly DbSet<T> _dbEntitySet;
/// <summary>
/// Default constructor
/// </summary>
/// <param name="context">The database context</param>
protected Service(DbContext context)
{
// Assign our context and entity set
_context = context ?? throw new ArgumentNullException(nameof(context));
_dbEntitySet = context.Set<T>();
}
/// <summary>
/// Gets all the entities
/// </summary>
/// <param name="includes">Option includes for eager loading</param>
/// <returns></returns>
public IQueryable<T> List(params string[] includes)
{
// Create a query
IQueryable<T> query = _dbEntitySet;
// For each include, append to our query
if (includes != null) foreach (var include in includes) query = query.Include(include);
// Return our query
return query;
}
/// <summary>
/// Creates an entity
/// </summary>
/// <param name="model"></param>
public void Create(T model) => _dbEntitySet.Add(model);
/// <summary>
/// Updates an entity
/// </summary>
/// <param name="model"></param>
public void Update(T model) => _context.Entry(model).State = EntityState.Modified;
/// <summary>
/// Removes an entity
/// </summary>
/// <param name="model"></param>
public void Remove(T model) => _dbEntitySet.Remove(model);
/// <summary>
/// Saves the database context changes
/// </summary>
/// <returns></returns>
public async Task SaveChangesAsync()
{
try
{
// Save the changes to the database
await _context.SaveChangesAsync();
}
catch (DbEntityValidationException ex)
{
// Retrieve the error messages as a list of strings.
var errorMessages = ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.ErrorMessage);
// Join the list to a single string.
var fullErrorMessage = string.Join("; ", errorMessages);
// Combine the original exception message with the new one.
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
// Throw a new DbEntityValidationException with the improved exception message.
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
}
/// <summary>
/// Executes a stored procedure in sql
/// </summary>
/// <param name="procedure">The name of the sproc</param>
/// <param name="parameters">the sql params for the sproc</param>
/// <returns></returns>
public DbRawSqlQuery<T> ExecuteProcedure(string procedure, List<SqlParameter> parameters) => _context.Database.SqlQuery<T>($"exec {procedure} {CreateQueryStringFromParams(parameters)}");
/// <summary>
/// Dispose
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Creates the input string to run sprocs in sql with EF by converting the sql params into a nice string
/// </summary>
/// <param name="parameters"></param>
/// <returns></returns>
private static string CreateQueryStringFromParams(IEnumerable<SqlParameter> parameters)
{
var response = "";
var list = parameters as IList<SqlParameter> ?? parameters.ToList();
var length = list.Count;
for (var i = 0; i < length; i++)
{
response += $"{list[i].ParameterName}=\"{list[i].Value}\"";
if (i != length - 1) response += ", ";
}
return response;
}
/// <summary>
/// Disposes of any attached resources
/// </summary>
/// <param name="disposing">A boolean indicating whether the object is being disposed</param>
protected virtual void Dispose(bool disposing)
{
// If we are disposing, dispose of our context
if (disposing) _context.Dispose();
}
}
然后我创建了这个提供者:
public class DataProvider<T> where T : class
{
private readonly Service<T> _service;
public DataProvider(Service<T> service) => _service = service;
public IQueryable<T> List(params string[] includes) => _service.List(includes);
}
像这样注入到我的控制器中:
/// <summary>
/// Used to get the cameras that are currently available
/// </summary>
public class CameraAvailabilitiesController : AvailabilitiesController<CameraAvailability>
{
/// <summary>
/// Default constructor
/// </summary>
/// <param name="service"></param>
public CameraAvailabilitiesController(DataProvider<CameraAvailability> service)
: base(service)
{ }
}
但是当我尝试运行我的项目并获取我的相机时,我收到了这个错误:
找不到类型“r3plica.Service`1[[Products.Data.Models.CameraAvailability, Products.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]”的可访问构造函数。
有谁知道我做错了什么?
解决方案
protected Service(DbContext context)
- 构造函数应该像这样公开:
public Service(DbContext context)
推荐阅读
- cordova - 使用cordova自动向高音扬声器发送推文
- php - 无法从本地 PHP 应用程序访问远程 IBM DB2
- spring - 如何测试发布者是否是反应堆弹簧中的缓存发布者?
- javascript - 如何在Javascript中提取给定字符串中的日期和时间
- python - Selenium python 在 Internet Explorer 的 driver.get('URL') 后卡住了
- java - 如何从java代码访问元素文件夹下string.json中定义的字符串等资源?
- angular - 成功登录Angular后重定向
- css - 如何在 Ant Design React 组件中水平对齐 col 内容?
- sql - SQL count(*)函数查询某棒球数据表说明
- android - 如何修复 Android Studio 北极狐中的预览选项卡错误