首页 / C# / c# – 如何通过接口解决这个问题?
c# – 如何通过接口解决这个问题?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 如何通过接口解决这个问题?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3599字,纯文字阅读大概需要6分钟。
内容图文
![c# – 如何通过接口解决这个问题?](/upload/InfoBanner/zyjiaocheng/793/5c1254eb09934cababa8467ca98f5915.jpg)
我正在使用实体框架,这就是我的问题所在,但它可能不相关,因为我认为这是一个通用的C#问题.
我有一个MyContext类,它有许多DbSet< T>属性.
为了对它进行单元测试,我编辑了MyContext,因此这些是IDbSet< T>相反,并嘲笑它. IDbSet< T>是实体框架的一部分,DbSet实现它,因此两者几乎完全相同.
一切都很像这样,因为我可以做到IDbSet< T>我可以做的一切DbSet< T>
除了一件事之外的一切–DbSet有一个叫做SqlQuery(..)的方法,我也希望能够从我的IDbSet中调用它.
由于我不能改变DbSet或IDbSet,这给我留下了一个难题.我无法理解我是如何做到这一点所以我的IDbSet能够以某种逻辑方式添加一个SearchQuery(..)方法.
那有意义吗?我很困惑所以我可能忽略了一些非常简单的东西,例如copy&粘贴IDbSet并重命名并添加SearchQuery().有任何想法吗?
解决方法:
编辑
我相信我得到了你想要的东西 – 到处都是包装纸,可能比它的价值更麻烦,但值得一看:
// 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# – 如何通过接口解决这个问题?全部内容,希望文章能够帮你解决c# – 如何通过接口解决这个问题?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。