服务层依赖注入

时间:2016-11-29 15:05:03

标签: c# ninject ioc-container

我正在创建一个可以调用服务层的Web API,我正在尝试学习依赖注入,(我希望使用ninject),但我不确定如何在服务层上创建依赖。

这是web api所称的内容。

enter image description here

这里的问题是,当调用IPersonService时,这个人会定义一个性别,它会有一个名字,一个角色和种族。我正在使用构造函数注入并且不确定是否应该调用GenderService或者我应该调用业务层(在这种情况下由Core定义)。

enter image description here

我是否应该像上图或

一样调用服务

enter image description here

这是我的人事服务的样子

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调用我的问题时,它听起来就像找到某个人的某些事情一样依赖。

2 个答案:

答案 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

过去几年帮助我很多的设计是基于消息的体系结构,其中用例由消息描述,实现由通用抽象描述(阅读thisthis)。事实证明,这些设计非常灵活和可维护,因为它们允许透明地添加横切关注点,并允许在不更改任何现有代码的情况下添加新功能。此类设计还允许将Web API层简化为一个简单的基础架构,在添加新功能时不需要更改。您可以阅读有关此概念的here(注意:该文章是关于WCF的,但Web API的概念是相同的),here是一个Github存储库,它显示了如何在WCF和Web API。

祝你在软件掌握方面取得好成绩。

答案 1 :(得分: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)
    {
    }
    
  2. 如果您绝对需要将这些方法保留在IPersonService中,那么您将在方法而不是构造函数中注入依赖项。

    关于服务或核心的依赖性,取决于您的服务的作用。如果您的服务只是调用Core,那么请自行转到Core。如果您的服务正在进行某些验证或其他任何操作,您可能希望依赖它来避免在PersonService中复制相同的代码。

相关问题