首页> C#>如何使ServiceStack与现有的MVC /服务/存储库模式一起使用

我试图围绕ServiceStack并利用它来公开RESTful服务.

我目前正在使用MVC / Service / Repository / UnitOfWork类型模式,在该模式下获取客户的基本操作可能如下所示:

MVC控制器操作->服务方法->存储库-> SQL服务器

我的问题是:

>我的SS服务返回什么?域对象?还是我退回DTO
    有一个客户集合?如果是这样,那是什么
    顾客?域对象或视图模型或??
> SS服务应该替换我的服务层吗?
>我在这里采用完全错误的方法吗?

我想我有点困惑如何使所有这些并存.

域对象

public class Customer
{
    public int Id {get;set;}
    public string FirstName {get;set;}
    public string LastName {get;set;}
}

查看模型

public class CustomerViewModel
{
    public int Id {get;set;}
    public string FirstName {get;set;}
    ....
}

控制者

public class CustomersController : Controller
{
    ICustomerService customerService;

    public CustomersController(ICustomerService customerService)
    {
        this.customerService = customerService;
    }

    public ActionResult Search(SearchViewModel model)
    {
        var model = new CustomersViewModel() {
            Customers = customerService.GetCustomersByLastName(model.LastName); // AutoMap these domain objects to a view model here
        };

        return View(model);
    }
}

服务

public class CustomerService : ICustomerService
{
    IRepository<Customer> customerRepo;

    public CustomerService(IRepository<Customer> customerRepo)
    {
        this.customerRepo = customerRepo;
    }

    public IEnumerable<Customer> GetCustomersByLastName(string lastName)
    {
        return customerRepo.Query().Where(x => x.LastName.StartsWith(lastName));
    }
}

解决方法:

首先,这只是个人喜好,我会摆脱您的存储库层,而直接从服务操作访问/验证您的数据.如果您只需要传递参数,那么就没有必要拥有所有这些额外的层.

在回答您的问题时:

1)您的服务应返回DTO(source),您提到您正在使用MVC应用程序,因此请确保在操作上使用IReturn接口,这将使您能够执行var客户之类的操作= client.Get(新的GetCustomers());在您的控制器操作中,请参阅here.如何使用该DTO由您决定,如果需要,可以将其用作ViewModel,如果需要其他来源的其他属性,则可以创建单独的ViewModel.

2)是的,ServiceStack是应用程序中的服务层,通常您需要所有交互都经过该层,因此不需要所有这些不同的层(我的第一点)该应用程序的体系结构要复杂得多.

3)我想是的,您似乎过度考虑了您的应用程序,删去了所有这些层

就上述示例和建议here而言,我将执行以下操作:

项目结构(这些可以是一个项目中的文件夹,也可以根据应用程序的大小分为不同的项目:)

Although for small projects with only a few services it’s ok for everything to be in a single project and to simply grow your architecture when and as needed.

- SamProject.Web
    App_Start
        AppHost.cs
    Controllers
        CustomerController.cs

- SamProject.ServiceInterface 
    Services
        CustomersService.cs
    Translators                 // Mappings from Domain Object > DTO
        CustomersTranslator.cs

- SamProject.Data               // Assumes using EF
    CustomersContext.cs
    Customer.cs

- SamProject.ServiceModel     
    Operations               
        CustomersService            
            GetCustomers.cs
            GetCustomer.cs
            CreateCustomer.cs           
    Resources
        CustomerDTO.cs

DTO:

public class CustomerDTO
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

操作方式:

[Route("/customers/{Id}")]
public class GetCustomer : IReturn<CustomerDTO>
{
    public int Id { get; set; }
}

[Route("/customers")]
public class GetCustomers : IReturn<IEnumerable<CustomerDTO>>
{
    public string LastName { get; set; }
}

服务:

public class CustomersService : Service
{
    private readonly CustomerContext _dbCustomerContext;

    public CustomersService(CustomerContext dbCustomerContext)
    {
        _dbCustomerContext = dbCustomerContext;
    }

    public object Get(GetCustomer request)
    {
        return _dbCustomerContext.Customers
               .FirstOrDefault(c => c.Id == request.Id)
               .Select(c => c.Translate());
    }

    public object Get(GetCustomers request)
    {
        if (string.IsNullOrEmpty(request.LastName))
        {
            return _dbCustomerContext.Customers.ToList()
                   .Select(c => c.Translate());
        }

        return _dbCustomerContext.Customers
               .Where(c => c.LastName == request.LastName).ToList()
               .Select(c => c.Translate());
    }
}

控制器:

public class CustomersController : Controller
{
    private readonly JsonServiceClient _client;

    public CustomersController(JsonServiceClient client)
    {
        _client = client;
    }

    public ActionResult Search(SearchViewModel model)
    {
        var customers = _client.Get(new GetCustomers
        {
            LastName = model.LastName
        });

        return View(customers);
    }

}

笔记

>我喜欢将DTO视为资源
>我想根据代码的意图将我的代码分离为结构化的文件夹结构,这稍后对代码库变得更大时有所帮助,但是在中小型应用程序中,您可能不需要分离代码像这样编码
>我没有谈论其他功能,例如日志记录,验证,IoC(仅显示具体实现)等.
>翻译是翻译器中的扩展方法,或者您可以使用内置的translator
>在ServiceModel中,我确实有一个明确定义的文件夹结构,但是,我的服务操作的名称空间只是SamProject.ServiceModel,而不是SamProject.ServiceModel.Operations.CustomersService.但是,我的资源在SamProject.ServiceModel.Resources命名空间中.

上一篇:c#-多个嵌套表-ServiceStack Ormlite


下一篇:Java异常处理