分离接口并使它们更通用
Separating interfaces and making them more generic
我有一个接口来定义我的records\models
public interface IStockItem
{
string Code { get; set; }
string Description { get; set; }
decimal FreeStock { get; set; }
}
最好将动作放到另一个界面中吗?
public interface IStockExport
{
IEnumerable<IStockItem> GetAll();
IEnumerable<IStockItem> GetStockByCode(string code);
decimal GetFreeStock(string code);
}
public interface IStockImport
{
void CreateItem<IStockItem>;
}
有没有更好的方法来做到这一点并使其更通用?这样我就可以与其他人共享操作界面 records\models?
其他 records\models 是销售订单、客户、地址。
总体思路是一个 Import\Export 程序,它将通过 API.
多个不同帐户包中的 create\export 销售订单
您也可以使用通用接口:
public interface IRecordExport<T> where T : IRecordBase
{
IEnumerable<T> GetAll();
IEnumerable<T> GetOneByCode(string code);
decimal GetFree(string code);
}
public interface IRecordImport<T> where T : IRecordBase
{
void CreateItem<T>();
}
你可以,但可能没有必要。基于方法的接口 classes 最适用于您希望具有与实现相关的多态性的地方。
在你的情况下,你想要的似乎是能够共享通用功能(基于IStockExport
接口)同时提供多态创建机制(基于IStockImport
) .
我建议你为 IStockExport
实现一个抽象基础 class ,它可以被所有不同类型的 IStockItem
继承(由于公共接口),然后派生classes 应该实现 IStockExport
,因为每个 Create<IStockItem>()
实现都会不同,但由于共同的行为可以以相同的方式使用(总是 returns IStockItem
对象) .
这是一种常见的模式,称为Repository Pattern
。
如果你想走这条路,你应该创建一个基础接口,Repository<T>
,例如:
public interface IRepository<T>
{
void Insert(T entity);
void Delete(T entity);
IEnumerable<T> SearchFor(Func<T, bool> predicate);
IEnumerable<T> GetAll();
T GetById(int id);
}
您可以让 IStockItem
实现一个 IEntity
接口,以便它可以为 GetById()
提供一个 ID,例如:
public interface IEntity
{
int ID { get; }
}
然后您将通过声明实现 class 来为 StockItem
等数据类型实现存储库。它可能开始有点像这样:
public class Repository<T> : IRepository<T> where T : class, IEntity
{
protected Table<T> DataTable;
public Repository(DataContext dataContext)
{
DataTable = dataContext.GetTable<T>();
}
...
您想要获取库存项目的存储库的代码可能如下所示:
using (var dataContext = new StockItemDataContext())
{
var StockItemRepository = new Repository<IStockItem>(dataContext);
...
这对于您想要的可能有点矫枉过正,但这是一般方法。
For full details see this excellent blog post.
以下是您可以如何开始为您的案例实施此模式:
public interface IRepository<T>
{
void Insert(T entity);
void Delete(T entity);
IEnumerable<T> SearchFor(Func<T, bool> predicate);
IEnumerable<T> GetAll();
T GetByCode(string code);
}
public interface IStockItem: IEntity
{
string Description { get; set; }
decimal FreeStock { get; set; }
}
public sealed class StockItem: IStockItem
{
public string Code { get; set; }
public string Description { get; set; }
public decimal FreeStock { get; set; }
}
public interface IEntity
{
string Code { get; }
}
public sealed class MyLowLevelDataAccess
{
public StockItem FindStockItem(string code)
{
return null; // Call your API here.
}
public void DeleteStockItem(string code)
{
// Call your API here.
}
public void InsertStockItem(StockItem item)
{
// Call your API here.
}
public IEnumerable<StockItem> FindAllItems()
{
return FindItemsMatching(x => true);
}
public IEnumerable<StockItem> FindItemsMatching(Func<StockItem, bool> predicate)
{
return null; // Call your API here and return all items matching the predicate.
}
}
public sealed class StockRepository: IRepository<StockItem>
{
private readonly MyLowLevelDataAccess _dataAccess;
public StockRepository(MyLowLevelDataAccess dataAccess)
{
_dataAccess = dataAccess;
}
public void Insert(StockItem entity)
{
_dataAccess.InsertStockItem(entity);
}
public void Delete(StockItem entity)
{
_dataAccess.DeleteStockItem(entity.Code);
}
public IEnumerable<StockItem> SearchFor(Func<StockItem, bool> predicate)
{
return _dataAccess.FindItemsMatching(predicate);
}
public IEnumerable<StockItem> GetAll()
{
return _dataAccess.FindAllItems();
}
public StockItem GetByCode(string code)
{
return _dataAccess.FindStockItem(code);
}
}
我有一个接口来定义我的records\models
public interface IStockItem
{
string Code { get; set; }
string Description { get; set; }
decimal FreeStock { get; set; }
}
最好将动作放到另一个界面中吗?
public interface IStockExport
{
IEnumerable<IStockItem> GetAll();
IEnumerable<IStockItem> GetStockByCode(string code);
decimal GetFreeStock(string code);
}
public interface IStockImport
{
void CreateItem<IStockItem>;
}
有没有更好的方法来做到这一点并使其更通用?这样我就可以与其他人共享操作界面 records\models?
其他 records\models 是销售订单、客户、地址。
总体思路是一个 Import\Export 程序,它将通过 API.
多个不同帐户包中的 create\export 销售订单您也可以使用通用接口:
public interface IRecordExport<T> where T : IRecordBase
{
IEnumerable<T> GetAll();
IEnumerable<T> GetOneByCode(string code);
decimal GetFree(string code);
}
public interface IRecordImport<T> where T : IRecordBase
{
void CreateItem<T>();
}
你可以,但可能没有必要。基于方法的接口 classes 最适用于您希望具有与实现相关的多态性的地方。
在你的情况下,你想要的似乎是能够共享通用功能(基于IStockExport
接口)同时提供多态创建机制(基于IStockImport
) .
我建议你为 IStockExport
实现一个抽象基础 class ,它可以被所有不同类型的 IStockItem
继承(由于公共接口),然后派生classes 应该实现 IStockExport
,因为每个 Create<IStockItem>()
实现都会不同,但由于共同的行为可以以相同的方式使用(总是 returns IStockItem
对象) .
这是一种常见的模式,称为Repository Pattern
。
如果你想走这条路,你应该创建一个基础接口,Repository<T>
,例如:
public interface IRepository<T>
{
void Insert(T entity);
void Delete(T entity);
IEnumerable<T> SearchFor(Func<T, bool> predicate);
IEnumerable<T> GetAll();
T GetById(int id);
}
您可以让 IStockItem
实现一个 IEntity
接口,以便它可以为 GetById()
提供一个 ID,例如:
public interface IEntity
{
int ID { get; }
}
然后您将通过声明实现 class 来为 StockItem
等数据类型实现存储库。它可能开始有点像这样:
public class Repository<T> : IRepository<T> where T : class, IEntity
{
protected Table<T> DataTable;
public Repository(DataContext dataContext)
{
DataTable = dataContext.GetTable<T>();
}
...
您想要获取库存项目的存储库的代码可能如下所示:
using (var dataContext = new StockItemDataContext())
{
var StockItemRepository = new Repository<IStockItem>(dataContext);
...
这对于您想要的可能有点矫枉过正,但这是一般方法。
For full details see this excellent blog post.
以下是您可以如何开始为您的案例实施此模式:
public interface IRepository<T>
{
void Insert(T entity);
void Delete(T entity);
IEnumerable<T> SearchFor(Func<T, bool> predicate);
IEnumerable<T> GetAll();
T GetByCode(string code);
}
public interface IStockItem: IEntity
{
string Description { get; set; }
decimal FreeStock { get; set; }
}
public sealed class StockItem: IStockItem
{
public string Code { get; set; }
public string Description { get; set; }
public decimal FreeStock { get; set; }
}
public interface IEntity
{
string Code { get; }
}
public sealed class MyLowLevelDataAccess
{
public StockItem FindStockItem(string code)
{
return null; // Call your API here.
}
public void DeleteStockItem(string code)
{
// Call your API here.
}
public void InsertStockItem(StockItem item)
{
// Call your API here.
}
public IEnumerable<StockItem> FindAllItems()
{
return FindItemsMatching(x => true);
}
public IEnumerable<StockItem> FindItemsMatching(Func<StockItem, bool> predicate)
{
return null; // Call your API here and return all items matching the predicate.
}
}
public sealed class StockRepository: IRepository<StockItem>
{
private readonly MyLowLevelDataAccess _dataAccess;
public StockRepository(MyLowLevelDataAccess dataAccess)
{
_dataAccess = dataAccess;
}
public void Insert(StockItem entity)
{
_dataAccess.InsertStockItem(entity);
}
public void Delete(StockItem entity)
{
_dataAccess.DeleteStockItem(entity.Code);
}
public IEnumerable<StockItem> SearchFor(Func<StockItem, bool> predicate)
{
return _dataAccess.FindItemsMatching(predicate);
}
public IEnumerable<StockItem> GetAll()
{
return _dataAccess.FindAllItems();
}
public StockItem GetByCode(string code)
{
return _dataAccess.FindStockItem(code);
}
}