ASP.NET MVC 5 解决方案架构改进 - 多个服务具有相同的方法和代码
ASP.NET MVC 5 solution architecture improvement - multiple services with the same methods and code
我目前正在使用 Unity 和 Entity Framework 构建 ASP.NET MVC 5 应用程序。
这是我的架构(解决方案包含多个项目):
- Bootstrapper:项目包含我的界面之间的 link 和存储库和服务的 class
- 数据:我的模型和数据库对象之间的映射。该项目也包含存储库。
- 域:这个域包含应用程序常量 + 我的存储库和服务的接口
- 模型:包含应用程序中使用的模型
- 服务:包含所有 class 服务
- Web:具有视图、控制器、视图模型等的实际应用程序...
这是我的问题:在多个服务中我有相同的方法(获取一个项目,检查它是否存在,...)并且这些方法在每个服务中都完全相同,除了它们不使用相同的存储库和相同的模型。
示例:
public IQueryable<Car> Search(string search)
{
#region Sanitize parameters + Contracts
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(search), Resources.Resources.SearchRequired);
search = StringHelper.SafePlainText(search);
Contract.Assume(search.Length <= 100 && search.Length > 1);
#endregion
return _carRepository.Search(StringHelper.SafePlainText(search));
}
我想要 "extract" 这些方法,这样我就不必一遍又一遍地重新创建相同的代码。
首先,我想创建一个抽象 class 我的服务从中继承,但我不知道如何将正确的存储库传递给母亲 class。
这是我试过的:
public abstract class Service<T>
{
public object Repository { get; set; }
protected Service(object repository)
{
Repository = repository;
}
public IQueryable<T> Search(string search)
{
#region Sanitize parameters + Contracts
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(search), Resources.Resources.SearchRequired);
search = StringHelper.SafePlainText(search);
Contract.Assume(search.Length <= 100 && search.Length > 1);
#endregion
return Repository.Search(StringHelper.SafePlainText(search));
}
}
但这当然行不通。
所以我想问问你们,如果至少有可能的话,你们是否知道我如何设法完成这项工作。
提前谢谢你,请原谅我的语言不好,我不是英语母语者。
Thibault.ce
首先,您可以从基础 class(可选)继承所有 entity framework 对象:http://fairwaytech.com/2013/09/using-a-common-base-class-across-entity-framework-database-first-entities/
然后,您可以创建一个通用 class "BaseRepository",它基于您创建的基础 class(或只是 "class")。 class 将包含所有泛型方法。在这个class中,可以使用entityframework方法"Set()"访问基础对象对应的table,其中returnstyped传入参数的DbSet .
之后您可以从 "BaseRepository" 继承所有存储库,并指定具体方法。
我用 2 tables 做了一个简单的例子:https://dotnetfiddle.net/9hurx9
感谢您的快速回答。
我设法重构了我的存储库,这是一个非常好的点,感谢您的解决方案。
但起初我的问题不是重构我的存储库,而是重构我的服务。我想执行与 Entities.Set()... 相同的过程...但是调用我的存储库。
示例:
我想从我的 CarService 中提取这个方法:
public IQueryable<Car> GetAll()
{
return _carRepository.GetAll();
}
并将其放在一个抽象的 class 服务中。像这样的东西:
public IQueryable<T> GetAll()
{
return Repository.GetAll();
}
但是如何将正确的存储库从 class CarService 传递到 class 服务?
其实很难解释..
但是非常感谢你的回答。它已经帮助了我。
我找到的最佳解决方案是创建一个通用的 class,它依赖于 2 种类型:存储库和实体。
A BaseService< T1, T2 > 接受参数 a "BaseRepository" 和 a "IEntity" 并且将包含所有通用方法。此 class 必须包含一个包含存储库实例的 属性。因此,您可以使用示例中所示的存储库。
然后你可以创建特定的服务 classes,比如 CarService 继承自 BaseService< CarRepository, Car >。
一个简单的例子,基于我之前回答的例子:
public class BaseService<TRepo, TEntity> where TRepo : BaseRepository<TEntity> where TEntity: IEntity
{
public TRepo Repository { get; set; }
public BaseService(TRepo repository)
{
this.Repository = repository;
}
public List<TEntity> GetAll()
{
return this.Repository.GetAll().ToList();
}
}
public class UserService : BaseService<UserRepository, User>
{
public UserService(UserRepository repository)
: base(repository)
{
}
public List<User> GetAllUserSortByName()
{
return this.Repository.GetAllUserSortByName();
}
}
你可以这样使用它:
YourEntities entities = new YourEntities();
UserRepository repo = new UserRepository(entities);
UserService service = new UserService(repo);
List<User> users = service.GetAllUserSortByName();
如果我的回答不够清楚,请告诉我。
编辑:
我目前正在使用 Unity 和 Entity Framework 构建 ASP.NET MVC 5 应用程序。
这是我的架构(解决方案包含多个项目):
- Bootstrapper:项目包含我的界面之间的 link 和存储库和服务的 class
- 数据:我的模型和数据库对象之间的映射。该项目也包含存储库。
- 域:这个域包含应用程序常量 + 我的存储库和服务的接口
- 模型:包含应用程序中使用的模型
- 服务:包含所有 class 服务
- Web:具有视图、控制器、视图模型等的实际应用程序...
这是我的问题:在多个服务中我有相同的方法(获取一个项目,检查它是否存在,...)并且这些方法在每个服务中都完全相同,除了它们不使用相同的存储库和相同的模型。
示例:
public IQueryable<Car> Search(string search)
{
#region Sanitize parameters + Contracts
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(search), Resources.Resources.SearchRequired);
search = StringHelper.SafePlainText(search);
Contract.Assume(search.Length <= 100 && search.Length > 1);
#endregion
return _carRepository.Search(StringHelper.SafePlainText(search));
}
我想要 "extract" 这些方法,这样我就不必一遍又一遍地重新创建相同的代码。
首先,我想创建一个抽象 class 我的服务从中继承,但我不知道如何将正确的存储库传递给母亲 class。
这是我试过的:
public abstract class Service<T>
{
public object Repository { get; set; }
protected Service(object repository)
{
Repository = repository;
}
public IQueryable<T> Search(string search)
{
#region Sanitize parameters + Contracts
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(search), Resources.Resources.SearchRequired);
search = StringHelper.SafePlainText(search);
Contract.Assume(search.Length <= 100 && search.Length > 1);
#endregion
return Repository.Search(StringHelper.SafePlainText(search));
}
}
但这当然行不通。
所以我想问问你们,如果至少有可能的话,你们是否知道我如何设法完成这项工作。
提前谢谢你,请原谅我的语言不好,我不是英语母语者。
Thibault.ce
首先,您可以从基础 class(可选)继承所有 entity framework 对象:http://fairwaytech.com/2013/09/using-a-common-base-class-across-entity-framework-database-first-entities/
然后,您可以创建一个通用 class "BaseRepository",它基于您创建的基础 class(或只是 "class")。 class 将包含所有泛型方法。在这个class中,可以使用entityframework方法"Set()"访问基础对象对应的table,其中returnstyped传入参数的DbSet .
之后您可以从 "BaseRepository" 继承所有存储库,并指定具体方法。
我用 2 tables 做了一个简单的例子:https://dotnetfiddle.net/9hurx9
感谢您的快速回答。
我设法重构了我的存储库,这是一个非常好的点,感谢您的解决方案。
但起初我的问题不是重构我的存储库,而是重构我的服务。我想执行与 Entities.Set()... 相同的过程...但是调用我的存储库。
示例:
我想从我的 CarService 中提取这个方法:
public IQueryable<Car> GetAll()
{
return _carRepository.GetAll();
}
并将其放在一个抽象的 class 服务中。像这样的东西:
public IQueryable<T> GetAll()
{
return Repository.GetAll();
}
但是如何将正确的存储库从 class CarService 传递到 class 服务? 其实很难解释..
但是非常感谢你的回答。它已经帮助了我。
我找到的最佳解决方案是创建一个通用的 class,它依赖于 2 种类型:存储库和实体。
A BaseService< T1, T2 > 接受参数 a "BaseRepository" 和 a "IEntity" 并且将包含所有通用方法。此 class 必须包含一个包含存储库实例的 属性。因此,您可以使用示例中所示的存储库。
然后你可以创建特定的服务 classes,比如 CarService 继承自 BaseService< CarRepository, Car >。
一个简单的例子,基于我之前回答的例子:
public class BaseService<TRepo, TEntity> where TRepo : BaseRepository<TEntity> where TEntity: IEntity
{
public TRepo Repository { get; set; }
public BaseService(TRepo repository)
{
this.Repository = repository;
}
public List<TEntity> GetAll()
{
return this.Repository.GetAll().ToList();
}
}
public class UserService : BaseService<UserRepository, User>
{
public UserService(UserRepository repository)
: base(repository)
{
}
public List<User> GetAllUserSortByName()
{
return this.Repository.GetAllUserSortByName();
}
}
你可以这样使用它:
YourEntities entities = new YourEntities();
UserRepository repo = new UserRepository(entities);
UserService service = new UserService(repo);
List<User> users = service.GetAllUserSortByName();
如果我的回答不够清楚,请告诉我。
编辑: