2009-02-14 22 views
12

Estoy tratando de determinar la mejor manera de diseñar un proyecto .NET Entity Framework para lograr un buen enfoque en capas. Hasta ahora lo he probado en un juego basado en navegar donde los jugadores poseen y operan planetas. Así es como yo lo tengo:.NET Diseño del proyecto del marco de la entidad (arquitectura)

Sitio Web

Este contiene toda la parte delantera.

C# Proyecto - MLS.Game.Data

Este contiene el archivo EDMX con todas mis asignaciones de datos. No hay mucho más aquí.

C# Proyecto - MLS.Game.Business

Este contiene varias clases que llamo como 'Managers' PlanetManager.cs. El administrador del planeta tiene varios métodos estáticos que se usan para interactuar con el planeta, como getPlanet (int planetID) que devolvería un objeto de código generado de MLS.Game.Data.

Desde el sitio web, voy a hacer algo como esto:

var planet = PlanetManager.getPlanet(1);

Devuelve un objetoplaneta del de la MLS.Game.Data (generado a partir de la EDMX). Funciona, pero me molesta hasta cierto punto porque significa que mi parte delantera tiene que hacer referencia a MLS.Game.Data. Siempre he pensado que la GUI solo debería hacer referencia al proyecto Business.

Además, he descubierto que mis clases de Gerente tienden a ser muy pesadas. Terminaré con docenas de métodos estáticos en ellos.

Entonces ... mi pregunta es: ¿cómo los demás diseñan sus proyectos ASP EF?

EDITAR

Después de un poco más sin embargo, hay elementos adicionales que me molestan. Por ejemplo, digamos que tengo mi objeto Planeta, que nuevamente es código generado por el asistente. ¿Qué pasa si llega el momento en que mi planeta necesita tener una propiedad especializada, decir "Población" que es un tipo de cálculo basado en otras propiedades del objeto Planeta. ¿Querría crear una nueva clase que herede de Planet y luego devolverla? (Hmm, me pregunto si esas clases están sellados por la EF?)

Gracias

+0

en respuesta a su edición - que es donde la separación de los datos y objetos ricos entra en su cuenta. los objetos ricos entienden cómo exponer sus propiedades mientras encapsulan las operaciones que los modifican. los DTO son meramente para transferencia de datos a la capa de persistencia y no requieren lógica. – flesh

Respuesta

3

puede probar con el siguiente para mejorar las cosas:

  • Use EF para ir a buscar dtos en su capa de datos, a continuación, utilizar estos dtos para poblar los objetos de negocio más ricos en su capa de negocio. Su UI solo necesitaría hacer referencia a la capa Business.
  • Una vez que haya creado los objetos comerciales enriquecidos, puede comenzar a internalizar parte de la lógica de las clases de administrador, limpiando eficazmente la capa empresarial.

Personalmente prefiero el modelo más rico que el modelo de administrador porque, como dices, terminas con una carga de métodos estáticos, que inevitablemente terminas encadenando dentro de otros métodos estáticos. Encuentro esto demasiado complicado y, lo que es más importante, más difícil de entender y garantizar la coherencia de tus objetos en un momento dado.

Si encapsula la lógica dentro de la clase en sí, puede estar más seguro del estado de su objeto, independientemente de la naturaleza de la persona que llama.

Una buena pregunta por cierto.

+0

Me gusta a dónde va su idea, sin embargo, ¿no estaría duplicando mucho trabajo? Por ejemplo, si un DTO tiene varias propiedades, es probable que vuelva a crear todas esas propiedades en su versión "más rica" ​​de la clase. ¿Derecha? – bugfixr

+0

Después de algo más: ¿alguna vez ha realizado clases en su capa BLL que hereden de los DTO en la capa de datos? Esto permitiría algo de personalización. ¿Pensamientos? ¿Mala idea? – bugfixr

+1

heredar aumentaría el acoplamiento entre las capas (en lugar de reducirlo) y podría terminar con dependencias de referencia circulares, lo que lo haría colapsar de todos modos. Sí, habría algo de duplicación, pero recuerde que EF puede generar sus DTO, así que no me preocuparía demasiado por eso ... – flesh

0

No soy un experto, pero que suena bastante bien para mí. Eso es similar a lo que tengo en mis soluciones, excepto que simplemente fusiono el proyecto EF con el proyecto empresarial. Mis soluciones no son tan grandes, y mis objetos no requieren mucha inteligencia, así que está bien para mí. También tengo una tonelada de métodos diferentes para cada una de mis clases estáticas de ayuda.

Si no desea que la capa de presentación conozca la capa de acceso a datos, entonces debe crear algunas clases intermedias, lo que probablemente sería mucho trabajo. Entonces, ¿cuál es el problema con su configuración actual?

+1

Las dependencias dificultan la prueba y modificación de capas individuales. Para un proyecto pequeño, probablemente sea de poca importancia. Pero para proyectos de mayor escala y duración, generalmente se recomienda tener 0 dependencias entre las capas mediante el uso de un contenedor de inversión de control e interfaces definidas. Esto actualmente es bastante complicado de hacer con las clases generadas por Entity Framework. –

2

En mi humilde opinión, su diseño actual está bien. Es perfectamente normal que su UI haga referencia a la capa 'Datos' cuando la está llamando. Creo que tal vez su preocupación surja debido a la terminología. Los 'Datos' que ha descrito se refieren con mayor frecuencia a la capa 'objetos comerciales' (BOL). Un diseño común sería tener una capa de lógica de negocios (BLL) que es su capa de 'Gerentes' y una capa de acceso a datos (DAL). En su escenario, LINQ to Entites (suponiendo que usará eso) es su DAL. Un patrón de referencia normal sería: -

La interfaz de usuario hace referencia a BLL y BOL. BLL refiera BOL y DAL (LINQ a Entites).

Eche un vistazo a this series of articles para más detalles.

+0

Veo tu punto. Aunque en el caso de EF, no tengo más remedio que combinar mi BOL con el DAL ya que el BOL es generado por el asistente que hace el EF. ¿Me estoy perdiendo algo? – bugfixr

+0

Lo siento, error de mi parte. El EF no es tu DAL. Cualquier capa que use para obtener elementos de la base de datos será su DAL, presumiblemente LINQ a Entitites. En ese caso, el modelo que describo aún se mantiene. Su BOL generado sigue siendo solo un BOL, usando el EF. Editaré la publicación. –

0

Su diseño se ve bien. yo hubiera añadido una capa/Común Utilidad

Web UI
Negocios capa Layer
DataObjects
Utilidades

2

En cuanto a su segunda pregunta (después de la edición) si necesita o desea agregar características a tus objetos EF puedes usar clases parciales. Haga clic derecho en el archivo EDMX y seleccione ver código.

O si esto no es suficiente para que pueda deshacerse del diseñador y escribir sus propias clases habilitadas EF.

Hay un (breve) discusión de las dos opciones aquí - http://msdn.microsoft.com/en-us/library/bb738612.aspx

0

yo añadiría dtos a la capa de negocio que son representaciones "objeto mudo" (es decir, sólo propiedades) de las entidades en la capa de datos. A continuación, sus clases "manager" ellos pueden regresar, tales como:

class PlanetManager 
{ 
    public static PlanetDTO GetPlanet(int id) { // ... } 
} 

y la interfaz de usuario sólo puede hacer frente a la capa BLL a través POCOs; el Administrador (lo que yo llamaría una clase "Mapeador") maneja toda la traducción entre los objetos y la capa de datos. Además, si necesita extender la clase, puede tener una propiedad "virtual" en el objeto DTO y hacer que Manager la traduzca a sus componentes.

1

cuanto a su segunda pregunta en la sección "EDIT":

Si no me equivoco, las clases generadas por EF no están sellados, y son PARCIALES clases, por lo que fácilmente se podría extender los sin tocar los archivos generados ellos mismos.

La clase generada será:

public partial class Planet : global::System.Data.Objects.DataClasses.EntityObject 
{ 
... 
} 

para que pueda crear fácilmente sus propios "PlanetAddons.cs" (o como se quiera llamarlo) para extender esta clase:

public partial class Planet 
{ 
property int Population {get; set;} 
... 
} 

Bastante limpio, ¿eh? No hay necesidad de derivar y crear jerarquías de objetos artificiales ....

Marc

Cuestiones relacionadas