我正在创建一个可以调用服务层的Web API,我正在尝试学习依赖注入,(我希望使用ninject),但我不确定如何在服务层上创建依赖。
这是web api所称的内容。
这里的问题是,当调用IPersonService时,这个人会定义一个性别,它会有一个名字,一个角色和种族。我正在使用构造函数注入并且不确定是否应该调用GenderService或者我应该调用业务层(在这种情况下由Core定义)。
我是否应该像上图或
一样调用服务这是我的人事服务的样子
namespace Service.Services
{
public class PersonService : IPersonService
{
private IPersonCore personCore = null;
private INameService nameService = null;
private IRoleService roleService = null;
private IGenderService genderService = null;
private IEthnicityService ethnicityService = null;
private IPrefixService prefixService = null;
private Person currUser;
public PersonService(IPersonCore _personcore, INameService _namecore, IRoleService _roleservice, IGenderService _genderservice, IEthnicityService _ethnicityservice, IPrefixService _prefixservice )
{
this.personCore = _personcore;
this.nameService = _namecore;
this.roleService = _roleservice;
this.genderService = _genderservice;
this.ethnicityService = _ethnicityservice;
this.prefixService = _prefixservice;
}
public IEnumerable<Person> GetAllPerson()
{
if (isAuthorized())
{
return this.personCore.GetPersons();
}
return null;
}
public Person GetPersonByID(int id)
{
if (isAuthorized())
{
return this.personCore.GetPersonByID(id);
}
return null;
}
public Person GetPersonByEmail(string email)
{
if (isAuthorized())
{
return this.personCore.GetPersonByEmail(email);
}
return null;
}
public IEnumerable<Person> GetPersonByName(string first, string last, string middle)
{
if(isAuthorized())
{
Name newname = this.nameService.CreateName(first, last, middle);
return this.personCore.GetPersonByName(newname);
}
return null;
}
public IEnumerable<Person> GetPersonWithRoles(IEnumerable<Roles> r)
{
}
public IEnumerable<Person> GetPersonWithDOB(DateTime d)
{
if (isAuthorized())
{
return this.personCore.GetPersonWithDOB(d);
}
return null;
}
public Person SetPersonRole(int id, Roles r)
{
}
public Person SetGender(int id, Gender g)
{
}
public Person SetEthnicity(int id, Ethnicity e)
{
}
public Person SetPrefix(int id, Prefix p)
{
}
public Person CreatePerson(Person p)
{
if (isAuthorized())
{
return personCore.AddPerson(p);
}
return null;
}
public Person UpdatePerson(Person p)
{
if (isAuthorized())
{
return personCore.UpdatePerson(p);
}
return null;
}
public Person ActivatePerson(int id)
{
if (isAuthorized())
{
return personCore.ActivatePerson(id);
}
return null;
}
public Person DeactivatePerson(int id)
{
if (isAuthorized())
{
return personCore.DeactivatePerson(id);
}
return null;
}
public bool DeletePerson(int id)
{
if (isAuthorized())
{
return personCore.DeletePerson(id);
}
return false;
}
protected bool isAuthorized()
{
//Probably move to common
return true;
}
}
}
当从Web API调用我的问题时,它听起来就像找到某个人的某些事情一样依赖。
答案 0 :(得分:1)
PersonService
类包含许多依赖项,因为您违反了Single Responsibility Principle。这个课有很多责任,每次添加新功能(这是Open/Closed Principle违规)时,你最终都会更改这个课程。此外,isAuthorized
方法是一个贯穿各领域的问题,本课程应该没有这个概念。
最重要的是,您将当前登录的用户注入PersonService
。这是运行时数据,constructing application components using runtime data is an anti-pattern。
有很多方法可以解决这个问题,但这一切都归结为理解SOLID原则。但是,这样做可能是一项艰巨的任务,特别是如果您刚刚开始使用DI和软件设计。你可以阅读很多关于这方面的书籍,例如罗伯特·C·马丁的the amazing work和关于依赖注射的书籍,如马克·西曼的Dependency Injection in .NET。
过去几年帮助我很多的设计是基于消息的体系结构,其中用例由消息描述,实现由通用抽象描述(阅读this和this)。事实证明,这些设计非常灵活和可维护,因为它们允许透明地添加横切关注点,并允许在不更改任何现有代码的情况下添加新功能。此类设计还允许将Web API层简化为一个简单的基础架构,在添加新功能时不需要更改。您可以阅读有关此概念的here(注意:该文章是关于WCF的,但Web API的概念是相同的),here是一个Github存储库,它显示了如何在WCF和Web API。
祝你在软件掌握方面取得好成绩。
答案 1 :(得分:1)
您可以通过两种方式简化此操作:
您的PersonService不会依赖于角色,性别,种族和前缀服务,因为您不会从其方法中调用它们。它是客户端代码调用的shell而不是直接调用这些服务本身。如果是这种情况,那么您可以通过获取这4个依赖项来简化您的PersonService:
private IRoleService roleService = null;
private IGenderService genderService = null;
private IEthnicityService ethnicityService = null;
private IPrefixService prefixService = null;
这些方法适用于各自的服务:
public Person SetPersonRole(int id, Roles r)
{
}
public Person SetGender(int id, Gender g)
{
}
public Person SetEthnicity(int id, Ethnicity e)
{
}
public Person SetPrefix(int id, Prefix p)
{
}
如果您绝对需要将这些方法保留在IPersonService中,那么您将在方法而不是构造函数中注入依赖项。
关于服务或核心的依赖性,取决于您的服务的作用。如果您的服务只是调用Core,那么请自行转到Core。如果您的服务正在进行某些验证或其他任何操作,您可能希望依赖它来避免在PersonService中复制相同的代码。