向 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)

最新更新