[英]Registering generic types with autofac
I have tried to get this to work by following this stack , but it isn't working for me. 我试图通过遵循此堆栈来使其工作,但是它对我不起作用。 I have this module
我有这个模块
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();
}
}
And I have this service: 我有这项服务:
/// <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();
}
}
And then I created this provider : 然后我创建了这个提供者 :
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);
}
Which is injected into my controllers like this: 像这样注入到我的控制器中:
/// <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)
{ }
}
But when I try to run my project and get my cameras, I get this error: 但是,当我尝试运行项目并获取相机时,出现以下错误:
No accessible constructors were found for the type 'r3plica.Service`1[[Products.Data.Models.CameraAvailability, Products.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'.
找不到类型为'r3plica.Service`1 [[Products.Data.Models.CameraAvailability,Products.Data,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]的可访问构造函数。
Does anyone know what I am doing wrong? 有人知道我在做什么错吗?
protected Service(DbContext context)
-构造函数应像这样公开:
public Service(DbContext context)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.