我在c#中有以下课程:
public class Customer{
public long Id { get; set;}
public String Firstname { get; set;}
public String Lastname { get; set;}
public Customer(long id, String firstname, String lastname){...}
}
public class Book{
public long Id { get; set;}
public String Title { get; set;}
public String Author{ get; set;}
public int NumberOfCopies{ get; set;}
public Book(long id, String title, String author, int numberofcopies){...}
}
我的存储库是通用的,界面如下:
public interface IGenericRepository<T> where T : class, new(){
Add(T entity);
Update(T entity);
Delete(T entity);
GetAll();
}
因此,要为Customer创建存储库,我将创建一个IGenericRepository&lt; Customer&gt;和书籍IGenericRepository&lt; Book&gt;。要从GUI访问这些方法,我需要一个方法,如:AddCustomer(long id,String firstname,String lastname)和一本书的相同,因为GUI不知道实体本身。我在想创建一个包含这些方法的CustomerService和BookService。 但是,我必须为我添加的每个实体创建一个新的服务。
我的问题是,如何使这项服务具有通用性,并仍然保留实体构造函数中的参数?
要说清楚,我想要一个通用的Service类,它可以添加书籍和客户,但使用相同的方法。例如:
Add(<constructor parameters of T>)
将从Controller类调用此方法,该类将具有所有服务。然后,GUI可以通过控制器访问这些服务方法。
这可能吗?如果有,怎么样?如果不是,有没有更好的解决方案来实现这一目标?
提前致谢!
答案 0 :(得分:1)
一种选择是根据需要接受参数,例如: G:
public void Add<T>(params object param) { ... }
T
是您要创建的类型。通过反射检查哪些构造函数可用,选择适合参数列表的构造函数。然后实例化对象。瞧。
答案 1 :(得分:0)
我会将IRepository<t>
方法Add(T entity)
更改为Add(object entity)
。这样,您就可以为任何实体使用完全相同的代码。
答案 2 :(得分:0)
我通常看到它完成的方式是你有以下内容:
1。 定义通用添加,更新,删除等的接口:
public interface IGenericRepository<T> where T : class
{
Add(T entity);
Update(T entity);
Delete(T entity);
GetAll();
}
2。 一个通用存储库,它接受您将持久保存到数据存储的不同类型。
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private connectionInformation;
public GenericRepository<T>(object connectionInformation)
{
// do something with the connection info, dbContext, etc...
}
public T Add(T entity)
{
// implementation...
}
public T Update(T entity)
{
// implementation...
}
public T Delete(T entity)
{
// implementation...
}
public List<T> GetAll()
{
// implementation...
}
}
3。 一个工作单元,用于为不同的具体类型设置通用存储库的实例。
public class UnitOfWork
{
private object connectionInformation;
public UnitOfWork(object connectionInformation)
{
// set up your connection information
this.connectionInformation = connectionInformation;
this.CustomerRepository = new GenericRepository<Customer>(connectionInformation);
this.BookRepository = new GenericRepository<Book>(connectionInformation);
}
public GenericRepository<Book> BookRepository { get; private set; }
public GenericRepository<Customer> CustomerRepository { get; private set; }
}
4。 可以实例化工作单元的服务/服务层&#34;你可以与之互动。它是负责处理每种类型的不同属性的服务,但数据保存和检索将通过unitOfWork处理。在您的服务中,您可以使用以下方法:
public void DeleteFirstBook()
{
var unitOfWork = new UnitOfWork(connnectionInformation);
var books = unitOfWork.BookRepository.GetAll();
if(books.Any())
{
unitOfWork.BookRepository.Delete(books.First());
}
}
您也可以为客户执行相同的操作。使服务层到位可以帮助您的代码过于紧密耦合。 &#34;数据层&#34;应该只负责与数据库交互(创建,读取,更新,删除)。如您所述,您的UI层也应该不知道如何创建新对象或与数据库交互。因此,服务变得很重要,因为它知道如何设置数据,在何处放置数据,以及如何将数据返回到UI。
希望它有所帮助!
答案 3 :(得分:0)
相当标准的方法是将“创建者”委托传递给您的存储库,我也不确定它是否符合您的目标:
public interface IGenericRepository<T> where T : class{
Add(Func<T> creator);
...
}
Repository<T> : IGenericRepository<T> where T : class
{
public Add(Func<T> creator)
{
T newOne = creator();
....
}
}
// usage
bookRepository.Add(() => new Book(42, "some title", ...));