How to convert this code to service pattern?

2019-08-17 07:00发布

问题:

Here is my code :

        [HttpGet]
    public ActionResult GetCategor(int catId)
    {
      using (uuEntities ems = new uuEntities())
      {
        return Json(ems.SupportSubCats.Where(x => x.CatID == catId).Select(
        x => new
        {
          SubId = x.SubCatID,
          SUbName = x.SubCatName
        }).ToList(), JsonRequestBehavior.AllowGet);
      }
    }

What I have tried :

In controller :

   [HttpGet]
    public ActionResult GetCategor(int catId)
    {
        return Json(_service.List(int catId), JsonRequestBehavior.AllowGet);
      }
    } 

In Service :

    public void List(int catId)
    {
      return new GenericRepository<SupportSubCategory>(_factory.ContextFactory)
        .Get(filter: (x => x.CatID == catId))
        .Select(x => new
        {
          SubId = x.SubCatID,
          SUbName = x.SubCatName
        }).ToList();
    }

I think my return type is incorrect please suggest me the solution. Near public void, i am getting an error that void can not return the list.

回答1:

A void methods does not return any value to it's caller. You can use an empty return in a void method only to exit the method - but you can't return any value.

This code is perfectly valid and widely used as a common practice:

public void DoSomething()
{
    if(<someCondition>)
    {
        return;
    }
    // The rest of the code will only be executed if <someCondition> evalualtes to false
}

Usually, you use this pattern when you are passing parameters into the method and need to validate them before actually performing the rest of the method.

This code, however, is not valid and will not compile:

public void DoSomething()
{
    if(<someCondition>)
    {
        return false; // Here is your compiler error...
    }
    // The rest of the code will only be executed if <someCondition> evalualtes to false
}

Following our conversation in the comments, you should probably create a class to hold the results of the Select instead of using an anonymous type, and return a list of that class from your method:

// Note: I've renamed your method to something a little bit more meaningful
public List<SubDetails> ListSubDetails(int catId) 
{
  return new GenericRepository<SupportSubCategory>(_factory.ContextFactory)
    .Get(filter: (x => x.CatID == catId))
    .Select(x => new SubDetails()
    {
      SubId = x.SubCatID,
      SUbName = x.SubCatName
    }).ToList();
}

...

public class SubDetails
{
    public Int SubId {get; set;} // I'm guessing int here...
    public string SUbName {get; set;} // I'm guessing string here...
 }