并排ASP.NET MVC网站ServiceStack新的服务端 [英] ServiceStack new service side by side ASP.NET MVC website

查看:118
本文介绍了并排ASP.NET MVC网站ServiceStack新的服务端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

范例为ServiceStack我没有看到一个单一的应用程序,ASP.NET MVC的网站,然后再做ServiceStack服务第二。

让我们来呈现产品通过浏览一个非常简单的ASP.NET MVC Web应用程序。它使用控制器,视图,模型和的ViewModels。

让我们说我们有产品它获取持续到文档数据库的模型。假设我们有 ProductViewModel 的视图模型它会从产品和显示MVC的Razor视图/ PartialView内的映射。

所以这是things..now假设我们要添加一个服务退回产品的各种客户喜欢Windows 8的应用程序的Web端。

如果请求/响应类完全从我们已经断开?我们的 ProductViewModel 可能已经包含一切,我们希望从服务返回。

既然我们已经有了产品(模型类),我们不能在API命名空间中另一个产品类..well我们可以但使事情不清楚,我想避免这种情况。

所以,我们应该引入独立 ProductRequest 类和 ProductRequestResponse (继承ProductViewModel)类的API命名空间?

像这样 ProductRequestResponse:ProductViewModel

我在说什么的,我们已经有模型和视图模型类和构建Request和Response类的SS服务,我们将不得不创建另一个两个文件,​​主要是从我们已有的类将所有内容复制。这看起来不是干了,它可能会遵循准则的担忧分离,但干也很重要,居然超过分离的一切(一切分离导致code重复)。

我想看到的是,其中一个Web应用程序已经取得的情况下,它目前拥有型号及的ViewModels,并返回​​网页上显示相应的意见,但可以扩展成一个功能齐全的服务,以支持程序的客户端?像AJAX客户端等等......我们已经具备。

另一件事:

如果你看看这个例子<一个href=\"https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/ServiceStack.MovieRest/MovieService.cs\">https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/ServiceStack.MovieRest/MovieService.cs

您会看到有电影 Request类和电影请求类(一个用于单个影片的要求,其他一个用于电影的列表)。因此,也有两项服务, MovieService MoviesService ,其中一个请求处理单个动画,其他一个是电影的一个流派。

现在,虽然我喜欢SS服务方式,我认为这是正确的,我不喜欢这种仅仅因为请求的类型的分离。如果我想通过导演的电影吗?请问我该发明还具有总监财产和另一个服务( MoviesByDirector ),因为它的另一个请求类?

我觉得样品应朝着一个服务为导向。有应对一切的电影必须在一个屋檐下。怎样才能做到这一点与ServiceStack?

 公共类ProductsService:服务
{
    私人只读IDocumentSession _session;
    私人只读ProductsHelperService _productsHelperService;
    私人只读ProductCategorizationHelperService _productCategorization;    公共类ProductRequest:IReturn&LT; ProductRequestResponse&GT;
    {
        公众诠释标识{搞定;组; }
    }    //这是否有意义?
    //请注意,我们使用ProductViewModel在我们的观点,它拥有我们会在服务响应还想一切
    公共类ProductRequestResponse:ProductViewModel
    {
    }    公共ProductRequestResponse的GetProducts(ProductRequest要求)
    {
        ProductRequestResponse响应=无效;
        如果(request.Id&GT; = 0)
        {
            变种产品= _session.Load&LT;产品及GT;(request.Id);
            response.InjectFrom(产品);
        }
        返回响应;
    }
}


解决方案

服务层是你最重要的合同

这是你所能创建你的整个系统中最重要的接口是外部面向服务合同,这是您的服务或应用程序的用户将绑定到,即现有的呼叫站点,往往不会得到了更新与code-基地 - 所有其他模式是次要的。

的DTO是远程服务

最佳实践

在使用DTO的(数据传输对象)的远程服务(的 Martin Fowler的建议后= http://msdn.microsoft.com/en-us/library/ff649585.aspx\">MSDN ),<一个href=\"http://www.palmmedia.de/Blog/2011/8/30/ioc-container-benchmark-performance-comparison\">ServiceStack鼓励使用清洁的,未受污染的波苏斯定义与应存放在很大程度上实现和依赖性,无.DLL一个明确的合同。这样做的好处可以让你能够重新利用类型的DTO用来与定义服务,-是,在你的 C#/。NET客户。 - 提供终端到终端类型的API,而无需使用任何code根或其他人工机械

干VS意图

让事情DRY不应该写明的意图,你应该避免干燥或的​​躲在继承,魔法属性或任何其他机制。具有清洁,定义良好的DTO提供参考,任何人都可以看看,看看每一个服务接受并返回一个单一来源,它可以让你的客户端和服务器开发者开始他们的工作马上和绑定到外部服务模式,而不执行具有被写入。

保持DTO的分离也让你自由地重新因数实施从内不破的外部客户端,即您的服务开始缓存响应或利用了的NoSQL解决方案与填充您的回答。

它也提供了权威的来源(也就是不被泄露或结合您的应用程序逻辑内部)的用于创建自动生成的元数据的页面,例如响应,扬鞭支持的XSD,WSDL文件等。

使用ServiceStack内置的自动映射

虽然我们鼓励保持独立的DTO模式,你并不需要维护自己的手动映射,你可以像使用 AutoMapper 或使用ServiceStack内置的自动映射支持,例如:

创建一个新的DTO的实例,填充在视图模型匹配属性:

  VAR DTO = viewModel.ConvertTo&LT; MyDto&GT;();

初​​始化DTO并与视图模型匹配属性来填充它:

  VAR DTO =新MyDto {A = 1,B = 2} .PopulateWith(视图模型);

初​​始化DTO和填充它的非默认在一个视图模型匹配属性:

  VAR DTO =新MyDto {A = 1,B = 2} .PopulateWithNonDefaultValues​​(视图模型);

初​​始化DTO和匹配那些标注了性能填充它在的Attr 属性的视图模型:

  VAR DTO =新MyDto {A = 1} .PopulateFromPropertiesWithAttribute&LT; attr指示&GT;(视图模型);

在映射逻辑变得更加复杂,我们喜欢用扩展方法,以保持code干燥,保持在一个地方的映射,它的容易从你的应用程序中的易耗品,例如:

 公共静态类MappingExtensions
{
    公共静态MyDto ToDto(此MyViewModel视图模型)
    {
        VAR DTO = viewModel.ConvertTo&LT; MyDto&GT;();
        dto.Items = viewModel.Items.ConvertAll(X =&GT; x.ToDto());
        dto.CalculatedProperty =计算(viewModel.Seed);
        返回DTO;
    }
}

这是现在很容易,只需耗:

  VAR DTO = viewModel.ToDto();

In the examples for ServiceStack I don't see a single application that is ASP.NET MVC website first and then made ServiceStack service second.

Let's take a very simple ASP.NET MVC web application that renders products through Views. It uses controllers, views, models and viewmodels.

Let's say we have a model of Product which gets persisted into a document DB. Let's assume we have a viewmodel of ProductViewModel which gets mapped from Product and display within MVC Razor View/PartialView.

so this is a web side of things..now let's assume we want to add a service returning products to various clients like the Windows 8 applications.

Should the request/response classes be completely disconnected from what we already have? Our ProductViewModel might already contain everything we want to return from the service.

Since we already have Product (model class) we can't have another Product class in the API namespace..well we could but that makes things unclear and I'd like to avoid that.

So, should we introduce standalone ProductRequest class and ProductRequestResponse (inherits ProductViewModel) class in the API namespace?

Like so ProductRequestResponse : ProductViewModel?

What i'm saying is, we already have the Model and ViewModel classes and to construct Request and Response classes for the SS service we would have to create another two files, mostly by copying everything from the classes we already have. This doesn't look DRY to me, it might follow the separation of concerns guidelines but DRY is important too, actually more than separating everything (separating everything leads to duplication of code).

What I would like to see is a case where a web application has already been made, it currently features Models and ViewModels and returns the appropriate Views for display on the Web but can be extended into a fully functional service to support programmatic clients? Like AJAX clients etc...with what we already have.

Another thing:

If you take a look at this example https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/ServiceStack.MovieRest/MovieService.cs

you will see there is Movie Request class and Movies Request class (one for single movie request, the other one for a list of movies). As such, there are also two services, MovieService and MoviesService, one dealing with requests for a single movie, the other one for a genre of movies.

Now, while I like SS approach to services and I think it is the right one, I don't like this sort of separation merely because of the type of request. What if I wanted movies by director? Would I be inventing yet another request class having a Director property and yet another service (MoviesByDirector) for it?

I think the samples should be oriented towards one service. Everything that has to deal with movies need to be under one roof. How does one achieve that with ServiceStack?

public class ProductsService : Service
{
    private readonly IDocumentSession _session;
    private readonly ProductsHelperService _productsHelperService;
    private readonly ProductCategorizationHelperService _productCategorization;

    public class ProductRequest : IReturn<ProductRequestResponse>
    {
        public int Id { get; set; }
    }

    // Does this make sense? 
    // Please note, we use ProductViewModel in our Views and it holds everything we'd want in service response also
    public class ProductRequestResponse : ProductViewModel
    {
    }

    public ProductRequestResponse GetProducts(ProductRequest request)
    {
        ProductRequestResponse response = null;
        if (request.Id >= 0)
        {
            var product = _session.Load<Product>(request.Id);
            response.InjectFrom(product);
        }
        return response;
    }
}

解决方案

The Service Layer is your most important Contract

The most important interface that you can ever create in your entire system is your external facing service contract, this is what consumers of your service or application will bind to, i.e. the existing call-sites that often won't get updated along with your code-base - every other model is secondary.

DTOs are Best practices for remote services

In following of Martin Fowler's recommendation for using DTOs (Data Transfer Objects) for remote services (MSDN), ServiceStack encourages the use of clean, untainted POCOs to define a well-defined contract with that should kept in a largely implementation and dependency-free .dll. The benefits of this allows you to be able to re-use typed DTOs used to define your services with, as-is, in your C#/.NET clients - providing an end-to-end typed API without the use of any code-gen or other artificial machinery.

DRY vs Intent

Keeping things DRY should not be confused with clearly stating of intent, which you should avoid trying to DRY or hide behind inheritance, magic properties or any other mechanism. Having clean, well-defined DTOs provides a single source of reference that anyone can look at to see what each service accepts and returns, it allows your client and server developers to start their work straight away and bind to the external service models without the implementation having been written.

Keeping the DTOs separated also gives you the freedom to re-factor the implementation from within without breaking external clients, i.e. your service starts to cache responses or leverages a NoSQL solution to populate your responses with.

It's also provides the authoritative source (that's not leaked or coupled inside your app logic) that's used to create the auto-generated metadata pages, example responses, Swagger support, XSDs, WSDLs, etc.

Using ServiceStack's Built-in auto-mapping

Whilst we encourage keeping separate DTO models, you don't need to maintain your own manual mapping as you can use a mapper like AutoMapper or using ServiceStack's built-in Auto Mapping support, e.g:

Create a new DTO instance, populated with matching properties on viewModel:

var dto = viewModel.ConvertTo<MyDto>();

Initialize DTO and populate it with matching properties on a view model:

var dto = new MyDto { A = 1, B = 2 }.PopulateWith(viewModel);

Initialize DTO and populate it with non-default matching properties on a view model:

var dto = new MyDto { A = 1, B = 2 }.PopulateWithNonDefaultValues(viewModel);

Initialize DTO and populate it with matching properties that are annotated with the Attr Attribute on a view model:

var dto = new MyDto { A=1 }.PopulateFromPropertiesWithAttribute<Attr>(viewModel);

When mapping logic becomes more complicated we like to use extension methods to keep code DRY and maintain the mapping in one place that's easily consumable from within your application, e.g:

public static class MappingExtensions
{
    public static MyDto ToDto(this MyViewModel viewModel)
    {
        var dto = viewModel.ConvertTo<MyDto>();
        dto.Items = viewModel.Items.ConvertAll(x => x.ToDto());
        dto.CalculatedProperty = Calculate(viewModel.Seed);
        return dto;
    }
}

Which is now easily consumable with just:

var dto = viewModel.ToDto();

这篇关于并排ASP.NET MVC网站ServiceStack新的服务端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆