c# - 我怎样才能通过接口(interface)解决这个问题?

标签 c# interface

我正在使用 Entity Framework ,这就是我的问题所在,但它可能不相关,因为我认为这是一个通用的 C# 问题。

我有一个 MyContext类有很多 DbSet<T>属性。

为了对其进行单元测试,我编辑了 MyContext 所以这些是 IDbSet<T>相反,并 mock 这一切。 IDbSet<T>是 Entity Framework 的一部分,DbSet 实现了它,因此两者几乎相同。

像这样一切都很好,因为我可以做到 IDbSet<T>我能做的一切 DbSet<T>

除了一件事之外的一切 - DbSet有一个方法叫做 SqlQuery(..)我也希望能够从我的 IDbSet 调用.

因为我不能改变 DbSetIDbSet ,这给我留下了一个难题。我不知道我该怎么做,所以我的 IDbSet能够有一个SearchQuery(..)方法以某种合乎逻辑的方式添加到其中。

这有意义吗?我很困惑,所以我可能忽略了一些非常简单的事情,比如复制和粘贴 IDbSet并重命名并添加 SearchQuery() .有什么想法吗?

最佳答案

编辑

我相信我得到了你要找的东西 - 到处都是包装器,可能比它的值(value)更麻烦,但值得一看:

// An interface which implements IDbSet<T> and adds on the method you want
public interface IExtendedDbSet<T> : IDbSet<T>
    where T : class
{
    DbSqlQuery<T> SqlQuery(string sql, object[] parameters);
}

// Implement this interface by wrapping around a regular DbSet<T>.
// You implement all the methods and properties by just wrapping the DbSet<T>
// calls
public class ExtendedDbSet<T> : IExtendedDbSet<T>
    where T : class
{
    private readonly DbSet<T> _dbSet;

    public ExtendedDbSet(DbSet<T> dbSet) { _dbSet = dbSet; }

    DbSqlQuery<T> IExtendedDbSet<T>.SqlQuery(string sql, object[] parameters)
    {
        return _dbSet.SqlQuery(sql, parameters);
    }

    T IDbSet<T>.Add(T entity) { return _dbSet.Add(entity); }
    T IDbSet<T>.Attach(T entity) { return _dbSet.Attach(entity); }
    TDerivedEntity IDbSet<T>.Create<TDerivedEntity>() { return _dbSet.Create<TDerivedEntity>(); }
    T IDbSet<T>.Create() { return _dbSet.Create(); }
    T IDbSet<T>.Find(params object[] keyValues) { return _dbSet.Find(keyValues); }
    ObservableCollection<T> IDbSet<T>.Local { get { return _dbSet.Local; } }
    T IDbSet<T>.Remove(T entity) { return _dbSet.Remove(entity); }
    IEnumerator<T> IEnumerable<T>.GetEnumerator() { return ((IEnumerable<T>)_dbSet).GetEnumerator(); }
    IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_dbSet).GetEnumerator(); }
    Type IQueryable.ElementType { get { return ((IQueryable)_dbSet).ElementType; } }
    Expression IQueryable.Expression { get { return ((IQueryable)_dbSet).Expression; } }
    IQueryProvider IQueryable.Provider { get { return ((IQueryable)_dbSet).Provider; } }
}

// A regular context class, no special interfaces to implement or
// custom properties or anything.
public class MyContext : DbContext
{
    public DbSet<Car> Cars { get; set; }
}

// An interface representing your context, which exposes extended DbSet<T>
// for your sets. Also define SaveChanges() and whatever else you may need
// to call on your context object.
public interface IMyContext
    : IDisposable
{
    IExtendedDbSet<Car> Cars { get; }
    int SaveChanges();
}

// A wrapper around your regular context. For each set, return an
// ExtendedDbSet<T> wrapper.
public class MyContextWrapper : IMyContext
{
    private readonly MyContext _myContext;

    public MyContextWrapper(MyContext myContext) { _myContext = myContext; }

    IExtendedDbSet<Car> IMyContext.Cars
    {
        get { return new ExtendedDbSet<Car>(_myContext.Cars); }
    }

    void IDisposable.Dispose()
    {
        _myContext.Dispose();
    }

    int IMyContext.SaveChanges()
    {
        return _myContext.SaveChanges();
    }
}

// Define your context variable as IMyContext, and create it
// by creating a wrapper around a regular context. The properties
// of the interface will be extended wrappers around your sets.
internal class Program
{
    private static void Main(string[] args)
    {
        using (IMyContext context = new MyContextWrapper(new MyContext()))
        {
            Console.WriteLine(context.Cars.SqlQuery("select 1", new object[0]));
        }
    }
}

关于c# - 我怎样才能通过接口(interface)解决这个问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17814568/

相关文章:

c# - 分解复杂多边形的算法

java - 接口(interface) : Java Language Specification

C# - 如何使用具有一个属性的接口(interface)在类之间进行通信

c# - 向下转换泛型参数时如何修复转换错误

c# - 长泛型集合类型的速记声明

c# - 无需用户交互即可获取 Office 365 API 访问 token

c# - 使用 TextWrapping 和 ScrollViewer 的大性能问题

c# - 更改 Nhibernate 连接字符串

JAVA类实现和扩展问题

C#接口(interface)继承到抽象类