tag route net for asp asp.net-mvc servicestack

route - ServiceStack nuevo servicio lado a lado ASP.NET MVC sitio web



tag helpers asp net core (2)

La capa de servicio es su contrato más importante

La interfaz más importante que puede crear en su sistema entero es su contrato de servicio externo, esto es a lo que se vincularán los consumidores de su servicio o aplicación, es decir, los sitios de llamadas existentes que a menudo no se actualizarán junto con su código -base: cualquier otro modelo es secundario.

Los DTO son las mejores prácticas para servicios remotos

Siguiendo las recomendaciones de Martin Fowler para usar DTO (objetos de transferencia de datos) para servicios remotos ( MSDN ), ServiceStack fomenta el uso de POCOs limpias y no contaminadas para definir un contrato bien definido que debe mantenerse en gran medida implementado y libre de dependencia. dll. Los beneficios de esto le permiten reutilizar los DTOs tipeados que se utilizan para definir sus servicios con, tal cual, en sus clientes C # / .NET , proporcionando una API de tipeo de extremo a extremo sin el uso de ningún código. gen u otra maquinaria artificial.

DRY vs Intent

Mantener las cosas SECAS no debe confundirse con la declaración clara de la intención, que debes evitar intentar SECAR o esconderte detrás de la herencia , las propiedades mágicas o cualquier otro mecanismo. Tener DTO limpios y bien definidos proporciona una única fuente de referencia que cualquier persona puede ver para ver qué acepta y devuelve cada servicio, permite a los desarrolladores de sus clientes y servidores comenzar su trabajo de inmediato y vincularse a los modelos de servicios externos sin la implementación habiendo sido escrito.

Mantener los DTO separados también le da la libertad de volver a factorizar la implementación desde dentro sin interrumpir a los clientes externos, es decir, su servicio comienza a almacenar respuestas en caché o aprovecha una solución NoSQL para completar sus respuestas.

También proporciona la fuente autorizada (que no se ha filtrado o acoplado dentro de la lógica de su aplicación) que se utiliza para crear páginas de metadatos generados automáticamente, respuestas de ejemplo, soporte Swagger, XSD, WSDL, etc.

Utilizando el mapeo automático incorporado de ServiceStack

Si bien recomendamos mantener modelos de DTO independientes, no necesita mantener su propia asignación manual, ya que puede usar un asignador como AutoMapper o usar la función Auto Mapping integrada de ServiceStack, por ejemplo:

Cree una nueva instancia de DTO, rellenada con propiedades coincidentes en viewModel:

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

Inicialice DTO y rellene con propiedades coincidentes en un modelo de vista:

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

Inicialice DTO y rellene con propiedades coincidentes no predeterminadas en un modelo de vista:

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

Inicialice DTO y rellene con propiedades coincidentes que se anoten con Attr Attribute en un modelo de vista:

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

Cuando la lógica de mapeo se vuelve más complicada, nos gusta utilizar métodos de extensión para mantener el código DRY y mantener la asignación en un lugar que sea fácilmente consumible desde su aplicación, por ejemplo:

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; } }

Que ahora es fácilmente consumible con solo:

var dto = viewModel.ToDto();

En los examples de ServiceStack, no veo una sola aplicación que sea el sitio web ASP.NET MVC primero y luego el servicio ServiceStack es el segundo.

Tomemos una aplicación web ASP.NET MVC muy simple que renderiza productos a través de Vistas. Utiliza controladores, vistas, modelos y modelos de vista.

Digamos que tenemos un modelo de Product que persiste en un documento DB. Supongamos que tenemos un modelo de vista de ProductViewModel que se asigna de Product y se muestra en MVC Razor View / PartialView.

así que este es un aspecto de la web. Ahora supongamos que queremos agregar un servicio que devuelva productos a varios clientes, como las aplicaciones de Windows 8.

¿Deberían las clases de solicitud / respuesta estar completamente desconectadas de lo que ya tenemos? Nuestro ProductViewModel ya puede contener todo lo que queremos devolver del servicio.

Como ya tenemos el Product (clase de modelo), no podemos tener otra clase de Product en el espacio de nombres de API ... bueno, podríamos hacerlo, pero eso hace que las cosas no estén claras y me gustaría evitar eso.

Entonces, ¿deberíamos introducir la clase ProductRequest y ProductRequestResponse (hereda ProductViewModel) en el espacio de nombres API?

Al igual que ProductRequestResponse : ProductViewModel ?

Lo que estoy diciendo es que ya tenemos las clases Model y ViewModel y para construir las clases Request y Response para el servicio SS tendremos que crear otros dos archivos, principalmente copiando todo de las clases que ya tenemos. Esto no me parece SECO, podría seguir las pautas de separación de preocupaciones, pero DRY también es importante, en realidad más que separar todo (separar todo conduce a la duplicación del código).

Lo que me gustaría ver es un caso en el que ya se ha hecho una aplicación web, actualmente presenta Modelos y Modelos de Vista y devuelve las Vistas apropiadas para mostrar en la Web, pero se puede extender a un servicio completamente funcional para soportar clientes programáticos. Como los clientes de AJAX, etc ... con lo que ya tenemos.

Otra cosa:

Si echa un vistazo a este ejemplo, https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/ServiceStack.MovieRest/MovieService.cs

verá que hay una clase de solicitud de Movie y una clase de solicitud de Movies (una para solicitud de película única, la otra para una lista de películas). Como tal, también hay dos servicios, MovieService y MovieService , uno que trata de solicitudes para una sola película, el otro para un género de películas.

Ahora, aunque me gusta el enfoque de SS para los servicios y creo que es el correcto, no me gusta este tipo de separación simplemente por el tipo de solicitud. ¿Qué pasa si quiero películas por director? ¿ MoviesByDirector inventando otra clase de solicitud que tenga una propiedad de Director y otro servicio más ( MoviesByDirector ) para ella?

Creo que las muestras deben estar orientadas a un servicio. Todo lo que tiene que ver con las películas debe estar bajo un mismo techo. ¿Cómo se logra eso con 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; } }


Si no está vinculado específicamente a ServiceStack y solo quiere "un servicio completamente funcional para admitir clientes programáticos ... con lo que ya tenemos", podría intentar lo siguiente: Haga que sus controladores devuelvan ViewResult o JsonResult función de la aceptación de la solicitud header - Request.AcceptTypes.Contains("text/html") o Request.AcceptTypes.Contains("application/json") .

Tanto ViewResult como JsonResult son ActionResult , por lo que la firma de acciones sigue siendo la misma, y ​​tanto View() como Json() aceptan un ViewModel. Además, si tiene un ControllerBase puede hacer un método base (por ejemplo, protected ActionResult RespondWith(Object viewModel) ) que llama a View () o Json () por lo que el cambio al código existente es mínimo.

Por supuesto, si sus ViewModels no son puros (es decir, tienen algunas cosas específicas de html o usted confía en alguna magia de ViewBag) entonces es un poco más de trabajo. Y no obtendrá SOAP u otros tipos de enlaces proporcionados por ServiceStack, pero si su objetivo es soportar una interfaz de datos JSON con cambios mínimos de código en la aplicación MVC existente, entonces podría ser una solución.

Lp