具有相同结构的控制器无法使用接口工作

本文关键字:接口 工作 控制器 结构 | 更新日期: 2023-09-27 17:56:26

我使用相同的结构分别为我的项目创建了 8 个模型和控制器,但现在这个结构不起作用。 它给了我这个错误:

当前类型 HelpDesk.Contracts.Repository.IRepositoryBase'1[HelpDesk.Model.Knowledgebase] 是一个接口,无法构造。是否缺少类型映射?

这是我的界面:

    namespace HelpDesk.Contracts.Repositories
{
    public interface IRepositoryBase<TEntity>
     where TEntity : class
    {
        void Commit();
        void Delete(object id);
        void Delete(TEntity entity);
        System.Linq.IQueryable<TEntity> GetAll();
        System.Linq.IQueryable<TEntity> GetAll(object filter);
        TEntity GetById(object id);
        TEntity GetFullObject(object id);
        System.Linq.IQueryable<TEntity> GetPaged(int top = 20, int skip = 0, object orderBy = null, object filter = null);
        void Insert(TEntity entity);
        void Update(TEntity entity);
    }
}

这是我的控制器:

namespace HelpDesk.WebUI.Controllers
{
    public class KnowledgebaseController : Controller
    {
        private DataContext db = new DataContext();
        IRepositoryBase<Knowledgebase> knowledgebases;
        public KnowledgebaseController(IRepositoryBase<Knowledgebase> knowledgebases)
        {
            this.knowledgebases = knowledgebases;
        }
public ActionResult ChooseSearchView()
        {
            string r = Session["LoggedUserRole"].ToString();
            if (r == "Technician")
            {
                return RedirectToAction("TechKnowledgebaseSearch");
            }
            else
            {
                return RedirectToAction("UserKnowledgebaseSearch");
            };
        }

我的数据上下文:

namespace HelpDesk.Contracts.Data
{
    public class DataContext : DbContext
    {
        /// <summary>
        /// you can either pass the NAME of a connection string (e.g. from a web.
        /// ), and explicitly i
        ///  </summary>
        public DataContext() : base("HelpDesk")
        {
        }
        /// <summary>
        /// any entity to be persisted must be declared here.
        /// </summary>
        /// 
        public DbSet<Category> Categories { get; set; }
        public DbSet<Knowledgebase> Knowledgebases { get; set; }
        public DbSet<Problem> Problems { get; set; }
        public DbSet<Role> Roles { get; set; }
        public DbSet<Ticket> Tickets { get; set; }
        public DbSet<TicketNote> TicketNotes { get; set; }
        public DbSet<TicketStatus> TicketStatuses { get; set; }
        public DbSet<TicketSubscription> TicketSubscriptions { get; set; }
        public DbSet<User> Users { get; set; }

    }
}

这是存储库库:

 namespace HelpDesk.Contracts.Repositories
{
    public abstract class RepositoryBase<TEntity> : HelpDesk.Contracts.Repositories.IRepositoryBase<TEntity> where TEntity : class
    {
        internal DataContext context;
        internal DbSet<TEntity> dbSet;
        public RepositoryBase(DataContext context)
        {
            this.context = context;
            this.dbSet = context.Set<TEntity>();
        }
        public virtual TEntity GetById(object id)
        {
            return dbSet.Find(id);
        }
        public virtual IQueryable<TEntity> GetAll()
        {
            return dbSet;
        }
        public IQueryable<TEntity> GetPaged(int top = 20, int skip = 0, object orderBy = null, object filter = null)
        {
            return null; // need to override in order to implement specific filtering and ordering
        }
        public virtual IQueryable<TEntity> GetAll(object filter)
        {
            return null; //need to override in order to implement specific filtering
        }
        public virtual TEntity GetFullObject(object id)
        {
            return null; //need to override in order to implement specific obect graph.
        }
        public virtual void Insert(TEntity entity)
        {
            dbSet.Add(entity);
        }
        public virtual void Update(TEntity entity)
        {
            dbSet.Attach(entity);
            context.Entry(entity).State = EntityState.Modified;
        }
        public virtual void Delete(TEntity entity)
        {
            if (context.Entry(entity).State == EntityState.Detached)
                dbSet.Attach(entity);
            dbSet.Remove(entity);
        }
        public virtual void Delete(object id)
        {
            TEntity entity = dbSet.Find(id);
        }
        public virtual void Commit()
        {
            context.SaveChanges();
        }
        public virtual void Dispose()
        {
            context.Dispose();
        }
    }
}

在这里,我有一个类似的结构化控制器,可以正常工作,另外还有 7 个这样的控制器:

namespace HelpDesk.WebUI.Controllers
{
    public class RoleController : Controller
    {
        private DataContext db = new DataContext();
        IRepositoryBase<Role> roles;
        public RoleController(IRepositoryBase<Role> roles)
        {
            this.roles = roles;
        }

当我单击此链接时,将引发异常:

<li>@Html.ActionLink("Knowledgebase", "ChooseSearchView", "Knowledgebase")</li>

具有相同结构的控制器无法使用接口工作

将知识库控制器构造函数更新为:

public KnowledgebaseController()
        {
            this.knowledgebases = new RepositoryBase<Knowledgebase>(db);
        }

并从 RepositoryBase<TEntity> 类中删除抽象以使其可实例化。

请注意:这只是一个快速解决方案。为了实现一个非常可靠的架构,便于简单的单元测试和松散耦合的类,我建议你实现一个工作单元。点击此链接 ASP.NET MVC 中实体框架的存储库模式和工作单元

不能实例化接口,必须实例化实现该接口的类。

public class RepositoryBase<T> : IRepositoryBase
{
    public RepositoryBase<T>()
    {
    }
    ...
}

然后使用该类型实例化您的具体类

IRepositoryBase<Knowledgebase> knowledgebases = new RepositoryBase<Knowledgebase>();

在此处阅读有关接口和实例化的更多信息:使用接口