Filters in DDD Repository

前端 未结 4 1101
遥遥无期
遥遥无期 2021-02-03 12:01

There is Campaign Entity and for that, I have CampaignRepository which have this functions

  1. public IList FindAll();
  2. public Campaign FindByCampaignNumber(st
相关标签:
4条回答
  • 2021-02-03 12:26

    I would go with creating two Specifications: TopCampaignSpec and CampaingCreatedSpec.

    var spec = CampaignCreatedSpec.ThisYear();
    var campaigns = CampaignsRepository.FindSatisfying(spec);
    

    CampaingCreatedSpec can also be replaced with more generic DateRange class if you need this functionality elsewhere:

    var thisYear = DateRange.ThisYear();
    var campaigns = CampaignsRepository.FindByDateRange(spec);
    

    I also highly recommend staying away from 'generic' repositories and entities. Please read this

    From DDD perspective it does not matter whether data access code is implemented as SQL/HQL/ICriteria or even web service call. This code belongs to repository implementation (data access layer). This is just a sample:

    public IList<Campaign> FindByDateRange(CampaignCreatedSpec spec) {
        ICriteria c = _nhibernateSession.CreateCriteria(typeof(Campaign));
        c.Add(Restrictions.Between("_creationDate", spec.StartDate, spec.EndDate));
        return c.List<Campaign>();
    }
    
    0 讨论(0)
  • 2021-02-03 12:28

    Here is how I would do this:

    class Campaigns{
      IEnumerable<Campaign> All(){...}
      IEnumerable<Campaign> ByNumber(int number){...}
      IEnumerable<Campaign> CreatedToday(){...}
      IEnumerable<Campaign> CreatedThisMonth(){...}
      IEnumerable<Campaign> CreatedThisYear(){...}
      IEnumerable<Campaign> Latest5(){...}
    
      private IQueryable<Campaign> GetSomething(Something something){
        //used by public methods to dry out repository
      }
    }
    

    Reasoning is simple - it matters by what You are interested to look for campaigns (that knowledge is part of Your domain). If we explicitly state functions to reflect that, we will always know it.


    Is it appropriate to add all this methods in campaign repository ?

    I don't see anything wrong with that.

    Arnis i want some code, how u implementing Created today function in domain itself, Are you injecting repository here in this function ? Thanks for your cooperation

    I wouldn't implement CreatedToday function in my domain. It would sit in repository and repository implementations should not be concern of domain. If You mean how I would use Campaign repository and if it should be used from domain - no, it should not be used from within of domain. If You mean if I would inject repository inside of repository - You are listening too much of xzibit.

    0 讨论(0)
  • 2021-02-03 12:42

    Have you considered implementing Specification pattern in your application? Maybe it looks like an overkill, but it may prove useful if your app will have some complex user filter options.

    class CampaignSpecification
    {
        public CampaignSpecification Number(string number);
        public CampaignSpecification DateBetween(DateTime from, date to);
        public CampaignSpecification Year(DateTime year);
    } //I have omitted all the AND/OR stuff it can be easily implemented with any SQL like query language
    

    Here is an example how loading from the repository may look like

    var  campaignList = CampaignRepository.load(
                new CampaignSpec()
                    .Number("2")
                    .Year(DateTime.Now);
    

    Also I'd like to add that it depends much on what kind of data access solution you are using, it makes implementing easier when you know what kind of API you will be using(Criteria API, SQL or whatever) so you can tweak your Specification interface to make its implementation simpler.

    UPDATE: if you are implementing specifications in .NET using linq and nHibernate please check out http://linqspecs.codeplex.com/

    0 讨论(0)
  • 2021-02-03 12:44

    You should be able to do all of the above with the following repository method:

    List<Campaign> findCampaigns(Date fromCreationDate, Date toCreationDate, int offset, Integer limit) {
    
       if (fromCreationDate != null) add criteria...
       if (toCreationDate != null) add criteria...
       if (limit != null) add limit...
    }
    

    This is how I do it and it works very well.

    0 讨论(0)
提交回复
热议问题