2012-04-03 15 views
7

Vamos a desarrollar una gran aplicación de escritorio empresarial muy pronto y he estado estudiando el enfoque WPF + PRISM + MVVM, tengo una buena comprensión de la mayoría de los conceptos y me encanta la modularidad que proporciona.WPF WCF Prism y MVVM - forma correcta de exponer entidades

Donde estoy teniendo problemas es con cómo diseñar la capa de servicios para obtener datos dentro y fuera, especialmente cuando este servicio es presentado por un módulo con la idea de que el módulo dependiente puede usarlo.

Quería resumir mis servicios de datos WCF dentro de los servicios de aplicaciones y usar ServiceLocator para resolver instancias concretas desde mis modelos de vista, sin embargo, estoy teniendo dificultades para encontrar la forma de hacerlo, principalmente debido a que mi estado es parte del servicio WCF.

Por ejemplo

Module1 Contiene Servicio WCF + Hormigón de servicios de aplicaciones (ISearchService) + Servicio WCF generado entidades (modelo)

Module1.Infastructure - contiene la siguiente interfaz para el servicio de aplicación

public interface ISearchService 
{ 
     ObservableCollection<Person> Search(string search); 
} 

esto se registrarían en el UnityContainer de manera que cualquier otro módulo puede obtener la implementación concreta introducida por el módulo.

Mi problema es que las Entidades (Person) se definen en el propio módulo (en el servicio WCF), por lo que introducir un servicio y esperar que otros módulos puedan usarlo significa que necesitan hacer referencia al módulo mismo no solo la infraestructura de los módulos, a menos que saque los servicios a otro ensamblado.

¿Debería exponer mis entidades que se generan automáticamente desde mi modelo EF de esta manera?

¿Alguien tiene una mejor solución?

+0

Puede que le interese [esta pregunta mía] (http://stackoverflow.com/q/4824058/302677) acerca de si el servicio WCF debe devolver los objetos 'Modelo', o un objeto de transferencia de datos. Terminé yendo con un DTO, y me resultó mucho más fácil hacer que devolviera un objeto de transferencia de datos y usar algo como [AutoMapper] (http://automapper.codeplex.com/) para asignar 'DTOs' a' Modelos' y viceversa – Rachel

+0

Me gusta esa idea, ¿usaría POCO's en Entity Framework básicamente sería lo mismo? –

Respuesta

1

Aquí está cómo lo hizo.

Actualmente estoy usando los servicios de Silverlight + PRISM + MVVM + WCF (RIA).

Con la arquitectura actual proyecto

  • Application.Domain: Contiene todas las primeras entidades de código EF incluyendo metadatos y validación de negocios. No incluye generación de base de datos.
  • Application.RIAServices: Este es el proyecto que contiene las clases autogeneradas del proyecto web de servicios de WCF RIA. Puedo hacer referencia a este proyecto tanto en WPF como en Silverlight.

  • Application.RIAServices.Web: proyecto web que contiene los DomainServices y el código de generación de base de datos mediante el uso de DbContext. este es el proyecto de enlace WCF RIA para la aplicación.RIAServices

  • Application.Infrastructure: Aquí es donde comienza. Porque al igual que usted, tengo una Persona/Servicio al Cliente que usa una interfaz ICustomerService. Como quiero utilizar este servicio, por ejemplo, toda la aplicación y no solo en el ModuleA, coloco esta interfaz en la Infraestructura. Todos los proyectos contienen una referencia a este proyecto.

  • Application.Modules.ModuleA -> Application.Modules.ModuleD: Módulos generales que proporcionan funcionalidad. Todos mis módulos (que usan WCF RIA Services) tienen una referencia a los proyectos Application.Infrastructure y Application.RIAServices.

  • Application.Shell: Startup project. tener el programa de arranque y registrar todos los módulos relevantes.

La pregunta de Reading Rachels me hizo pensar en ciertas cosas y solo quería dejar mi estructura sobre cómo lo hice. Es posible que tengas una idea al respecto. No quiero ir a DTO todavía porque las cosas como la validación están tan bien integradas en los servicios WCF RIA que se reflejan automáticamente en el cuadro de texto cuando algo está mal y muestran un mensaje de error. Mirando hacia adelante a oír su opinión y el resultado de la pregunta/tema

Editar:

Application.Domain también tiene una estructura separada aswell.

Tengo mis modelos. Solo propiedades de contenedor puro que deben asignarse a la base de datos. Entonces tengo mi carpeta de metadatos. Ahora para que esto funcione, necesito tener el mismo espacio de nombres que mi Entidad y hago que la entidad sea parcial. Creo un archivo Entity.metadata.cs y allí creo un internal sealed class EntityMetaData, copiando las propiedades y agregándole atributos. Al usar el atributo MetadataType sobre la clase Entity, agrega todos esos atributos al generador de código EF/WCF RIA.

Uno de esos atributos es el CustomValidation que utiliza una clase estática y un parámetro de método y valida la entidad en el servidor. O si crea el archivo con una extensión .shared.cs, se genera en el proyecto Application.RIAServices.

Posibilidad

Para tratar de responder a su pregunta, es posible que sólo tiene 1 opción y eso es lo que sugirió al principio. Puede crear un Proyecto de Infraestructura del Cliente.

este proyecto contiene la interfaz para el ICustomerService, la Entity/DTO/POCO como quiera, y tal vez incluso una implementación de este ICustomerService o el servicio WCF. Esto permite que todos sus módulos hagan referencia a este proyecto y, por lo tanto, no creen dependencias entre los módulos.

+0

cada recurso que he encontrado indica que los servicios de RIA no son compatibles con WPF, ¿no es así? –

+0

Quiero restringir mis servicios para que solo se ocupen de las entidades que son relevantes para el módulo, aunque puedan o no compartir la misma base de datos, mi problema es que termino con mi EF POCOS - mis entidades de servicio generadas que no realmente quiero exponer, entonces tal vez otro DTO - es solo un desastre con cada entidad representada miles de veces ... –

+0

@RichardFriend Necesito ver eso. Puedo hacer referencia al proyecto crear una referencia y crear un contexto de cliente. Pero no lo he visto en tiempo de ejecución. Echaré un vistazo. En cuanto a su problema, puede haber una forma de restringir el contenedor a la instancia de resolución. También tendrá un vistazo –

0

Puede definir una interfaz IPerson, haga que su entidad la implemente (utilizando clases parciales) y la use en su contrato. La otra opción, si lo prefiere, es dividir las definiciones de su entidad en su propio ensamblaje, o simplemente incluirlas en su ensamblaje de contratos.

+0

Pensé en eso, y me gusta la idea, sin embargo, es una gran cantidad de trabajo crear estas interfaces y mantenerlas sincronizadas con el modelo de datos, cuando se considera que las entidades se generan automáticamente. Interesado para ver cómo otras personas acercarse a esto –

+0

¿No puedes autogenerar una interfaz también?Al menos como punto de partida que te ahorraría un montón de tipeo. –

+0

¿qué hay de la creación de nuevas entidades, tendría que registrar la entidad concreta contra su interfaz y utilizar 'ServiceLocator' o contenedor de la unidad para resolver, esto simplemente se siente mal .. –

Cuestiones relacionadas