He creado un POCO de la clase del modelo y un repositorio de clase que se encarga de la persistencia. Desde el que POCO se puede acceder al repositorio, hay un montón de negocios de la lógica de tareas en el repositorio que no le parece correcto. Por lo que he leído, parece que necesito un servicio de la capa que se encuentra entre la interfaz de usuario de los consumidores y el repositorio de la capa. Lo que no estoy seguro de que es exactamente cómo se supone que funciona…

Además de la capa de servicio, debe haber también una separada capa de lógica de negocio, o es que la función de la capa de servicio?

Debe ser un servicio al repositorio?

Es la capa de servicio de la única manera que la interfaz de usuario puede instancia el modelo de objetos o el repositorio de proporcionar el nuevo modelo de instancia para el servicio?

Hago para poner mi parámetro, modelo y otras validaciones en la capa de servicio que hacen las cosas como comprobar para asegurarse de que una entrada es válida y que un elemento de actualizar existe en la base de datos antes de la actualización?

Puede el modelo de repositorio y la interfaz de usuario hacen llamadas a la capa de servicio, o es sólo para la interfaz de usuario para consumir?

Es la capa de servicio supone que todos los métodos estáticos?

Lo que sería una típica forma de llamar a la capa de servicio de la interfaz de usuario?

Lo validaciones debe estar en el modelo de vs la capa de servicio?

Aquí está el código de ejemplo para mi de las capas existentes:

public class GiftCertificateModel
{
    public int GiftCerticiateId {get;set;}
    public string Code {get;set;}
    public decimal Amount {get;set;}
    public DateTime ExpirationDate {get;set;}

    public bool IsValidCode(){}
}


public class GiftCertificateRepository
{
    //only way to access database
    public GiftCertificateModel GetById(int GiftCertificateId) { }
    public List<GiftCertificateModel> GetMany() { }
    public void Save(GiftCertificateModel gc) { }
    public string GetNewUniqueCode() { //code has to be checked in db }

    public GiftCertificateModel CreateNew()
    {
        GiftCertificateModel gc = new GiftCertificateModel();
        gc.Code = GetNewUniqueCode();
        return gc;
    }              
}

ACTUALIZACIÓN:
Actualmente estoy usando formularios web y clásico ADO.NET. Tengo la esperanza de pasar a la MVC y EF4 finalmente.

ACTUALIZACIÓN: muchas gracias a @Lester por su gran explicación. Ahora entiendo que tengo que agregar una capa de servicio para cada uno de mis repositorios. Esta capa será la ÚNICA forma en que la interfaz de usuario o de otros servicios se puede comunicar con el repositorio y contendrá cualquier validaciones que no caben en el objeto de dominio (por ejemplo, las validaciones que deben llamar a la repo)

public class GiftCertificateService()
{

    public void Redeem(string code, decimal amount)
    {
        GiftCertificate gc = new GiftCertificate();
        if (!gc.IsValidCode(code))
        {
            throw new ArgumentException("Invalid code");
        }

        if (amount <= 0 || GetRemainingBalance(code) < amount)
        {
            throw new ArgumentException("Invalid amount");
        }

        GiftCertificateRepository gcRepo = new GiftCertificateRepository();
        gcRepo.Redeem(code, amount);
    }

    public decimal GetRemainingBalance(string code)
    {
        GiftCertificate gc = new GiftCertificate();            
        if (!gc.IsValidCode(code))
        {
            throw new ArgumentException("Invalid code");
        }

        GiftCertificateRepository gcRepo = new GiftCertificateRepository();
        gcRepo.GetRemainingBalance(code);
    }

    public SaveNewGC(GiftCertificate gc)
    {
        //validates the gc and calls the repo save method
        //updates the objects new db ID
    }

}

Preguntas

  1. Agrego el mismo (y posiblemente más) de las propiedades para el servicio como tengo en mi modelo (cantidad, código, etc) ¿o solo me ofrecen métodos que aceptan GiftCertificate objetos y directa de los parámetros?

  2. Puedo crear una instancia predeterminada de la GiftCertificate entidad cuando el Servicio constructor es llamado o simplemente crear otros nuevos según sea necesario (por ejemplo, para la validación de métodos en el servicio que necesita para llamar a los métodos de validación en la entidad? También, la misma pregunta acerca de la creación de un repositorio predeterminado ejemplo…?

  3. Sé que expone la funcionalidad de la repo a través de el servicio, yo también exponer los métodos de la entidad (por ejemplo, IsValidCode, etc)?

  4. Es ok para la interfaz de usuario para la creación de un nuevo GiftCertificate objeto directamente, sin pasar por el servicio (por ejemplo, para llamar a la validación de parámetros de los métodos de la entidad). Si no, ¿cómo aplicarla?

  5. Sobre la capa de interfaz de usuario, cuando quiero crear un nuevo certificado de regalo, ¿debo llamar a la modelo/servicio de validaciones (como IsValidExpirationDate, etc) directamente desde la capa de interfaz de usuario O no me hidrato el objeto en primer lugar, a continuación, pasar a ser validado y, a continuación, volver algún tipo de validación resumen de vuelta a la interfaz de usuario?

También, si quiero Redimir de la capa de interfaz de usuario, hago la primera llamada a la modelo/servicio de validación de los métodos de la interfaz de usuario para dar la retroalimentación de los usuarios y, a continuación, llamar a la Canjear método que se ejecutará la misma comprueba de nuevo internamente?

Ejemplo para el servicio de llamadas a hacer un Canjear el funcionamiento de la interfaz de usuario:

string redeemCode = RedeemCodeTextBox.Text;

GiftCertificateService gcService = new GiftCertificateService();
GiftCertificate gc = new GiftCertificate(); //do this to call validation methods (should be through service somehow?)

if (!gc.IsValid(redeemCode))
{
    //give error back to user
}

if (gcService.GetRemainingBalance(redeemCode) < amount)
{
    //give error back to user
}

//if no errors
gcService.Redeem(code,amount);

Ejemplo para la creación de un nuevo certificado de Regalo de interfaz de usuario:

GiftCertificateService gcService = new GiftCertificateService();
GiftCertificate gc = new GiftCertificate();

if (!gc.IsValidExpDate(inputExpDate))
{
    //give error to user..
}

//if no errors...
gc.Code = gcService.GetNewCode();
gc.Amount = 10M;
gc.ExpirationDate = inputExpDate;
gcService.SaveNewGC(gc);
//method updates the gc with the new id...

Algo se siente mal acerca de la manera de GCs se crean y cómo las validaciones están separados entre entidad/servicio. El usuario/consumidor no tiene que estar preocupado con lo que las validaciones se en que lugar… consejos?

InformationsquelleAutor jpshook | 2011-05-26

3 Comentarios

  1. 42

    Echa un vistazo a S#arp Architeture . Es como una de las mejores prácticas marco arquitectónico para la construcción de ASP.NET aplicaciones de MVC. La arquitectura general de patrón es tener 1 repositorio por la entidad que es responsable sólo para el acceso a datos y 1 de servicio al repositorio de la que es responsable sólo de la lógica de negocio y la comunicación entre los controladores y servicios.

    Para responder a sus preguntas con base en S#arp Architeture:

    Además de la capa de servicio, debe haber también una separada capa de lógica de negocio, o es que la función de la capa de servicio?

    Modelos debe ser responsable de la validación de nivel de campo (ex. el uso de campo requerido atributos), mientras que los controladores pueden validar los datos antes de guardar (ex. comprobación del estado antes de guardar).

    Caso de que exista una capa de servicio al repositorio?

    Sí, debe ser una servicio por repositorio (no 1 de la capa de servicios por repositorio, pero estoy adivinando que significaba eso).

    Es la capa de servicio de la única manera que la interfaz de usuario puede instancia el modelo de objetos o el repositorio de proporcionar el nuevo modelo de instancia para el servicio?

    Repositorios y servicios puede devolver una sola entidad, una colección de entidades, o de objetos de transferencia de datos (Dto) como se requiere. Los controladores de pasar estos valores a un constructor estático método en el modelo, que devuelve una instancia del modelo.

    ex DTOs:

    GiftCertificateModel.CreateGiftCertificate(int GiftCerticiateId, string Code, decimal Amount, DateTime ExpirationDate)

    Hago para poner mi parámetro, modelo y otras validaciones en la capa de servicio que hacen las cosas como comprobar para asegurarse de que una entrada es válida y que un elemento de actualizar existe en la base de datos antes de la actualización?

    Modelos de validar a nivel de campo los valores de ex. asegurarse de que la entrada es válida por la comprobación de los campos requeridos, la edad o rango de fechas, etc. Los servicios deberían hacer cualquier validación necesaria que requiere comprobación fuera de el valor de modelo ex. La comprobación de que el certificado de regalo no ha sido redimido sin embargo, la comprobación de las propiedades de la tienda con el certificado de regalo es para).

    Puede el modelo de repositorio y la interfaz de usuario hacen llamadas a la capa de servicio, o es sólo para la interfaz de usuario para consumir?

    Controladores y otros servicios deben ser los únicos en hacer llamadas a la capa de servicio. Los servicios deben ser el único que hace que la realización de llamadas a los repositorios.

    Es la capa de servicio supone que todos los métodos estáticos?

    Que puede ser, pero es más fácil de mantener y ampliar si no lo están. Los cambios a las entidades y la adición o eliminación de las subclases son más fáciles de cambiar si hay 1 servicio por entidad /subclase.

    Lo que sería una típica forma de llamar a la capa de servicio de la interfaz de usuario?

    Algunos ejemplos de controladores de llamar a la capa de servicio:

    giftCertificateService.GetEntity(giftCertificateId); (which in turn is just a call to the giftCertificateRepository.GetEntity(giftCertificateId)
    
    giftCertificateService.Redeem(giftCertificate);

    Lo validaciones debe estar en el modelo de vs la capa de servicio?

    Ya se haya respondido anteriormente.

    ACTUALIZACIÓN

    Ya que usted está utilizando Formularios web puede ser un poco más difícil de comprender algunos de los conceptos pero todo lo que he mencionado es aplicable, ya que lo que estoy describiendo es un general paradigma MVC. ADO.NET para el acceso a datos no importa ya que los datos de acceso es independiente a través de repositorios.

    Agrego el mismo (y posiblemente más) de las propiedades para el servicio como tengo en mi modelo (cantidad, código, etc) ¿o solo me ofrecen métodos que aceptan GiftCertificate objetos y directa de los parámetros?

    Usted necesita para buscar en los servicios como exactamente lo que su nombre implica, las acciones que los controladores pueden invocar. Usted no necesita las propiedades que se definen en el modelo puesto que ya están disponibles en el modelo.

    Puedo crear una instancia predeterminada de la GiftCertificate entidad cuando el Servicio constructor es llamado o simplemente crear otros nuevos según sea necesario (por ejemplo, para la validación de métodos en el servicio que necesita para llamar a los métodos de validación en la entidad? También, la misma pregunta acerca de la creación de un repositorio predeterminado ejemplo…?

    Controladores y servicios deben tener campos privados para los servicios y repositorios respectivamente. Usted no debe crear instancias para cada acción o método.

    Sé que expone la funcionalidad de la repo a través de el servicio, yo también exponer los métodos de la entidad (por ejemplo, IsValidCode, etc)?

    No muy seguro de lo que quieres decir aquí. Si los servicios de devolución de las entidades, a continuación, estos métodos en las entidades que ya están expuestos. En caso de volver a DTOs entonces eso implica que usted está interesado sólo en cierto tipo de información.

    Para la validación puedo ver por qué estás un poco preocupado, ya que no hay validación realizada directamente sobre el modelo y otros tipos de validación que se realiza en los servicios. La regla de oro que yo he utilizado es que si la validación requiere de llamadas a la base de datos, entonces se debe hacer en la capa de servicio.

    Es ok para la interfaz de usuario para la creación de un nuevo GiftCertificate objeto directamente, sin pasar por el servicio (por ejemplo, para llamar a la validación de parámetros de los métodos de la entidad). Si no, ¿cómo aplicarla?

    En la capa de interfaz de usuario, cuando quiero crear un nuevo certificado de regalo, ¿debo llamar a la modelo/servicio de validaciones (como IsValidExpirationDate, etc) directamente desde la capa de interfaz de usuario O no me hidrato el objeto en primer lugar, a continuación, pasar a ser validado y, a continuación, volver algún tipo de validación resumen de vuelta a la interfaz de usuario?

    Para estas 2 preguntas le permite ir a través de un escenario:

    El usuario ingresa la información para crear un certificado nuevo y se somete. No hay campo de validación de nivel de modo que si un cuadro de texto es nulo o si la cantidad es negativa, se produce un error de validación. Suponiendo que todos los campos son válidos, el controlador se llame el servicio de gcService.Save(gc).

    El servicio de verificación otras lógica de negocio, tales como si la tienda ya ha emitido demasiados certificados de regalo. Se devuelve un enum para el estado si hay varios códigos de error o lanza una excepción con la información de error.

    Por último, el servicio de llamadas gcRepository.Save(gc).

    • You rock! finalmente empezando a tirar todos juntos. Yo debería haber notado en el post que estoy usando formularios web y ADO clásico para el acceso a datos. Por favor vea mis preguntas adicionales y el código de arriba y me dejó saber sus pensamientos. Todavía estoy un poco difusa en cómo crear una versión nueva GiftCertificate objetos y validar los parámetros de la capa de interfaz de usuario.
    • Actualizado con las respuestas a sus preguntas nuevas. Me alegra ser de ayuda, pero yo creo que va a ser mucho más fácil y el sentido más rápidamente si se utiliza ASP.NET MVC. Aunque, como he mencionado el paradigma MVC es aún válida en WebForms.
    • Por favor revisar mi interfaz de usuario el código de llamada de muestras y quiero saber si eso es lo que se debe trabajar? Para el nivel de campo validaciones en la interfaz de usuario, en caso de no llamar a los métodos de validación en el modelo y/o servicio, según sea necesario? También, a partir de lo que usted está diciendo, está bien para la interfaz de usuario para crear gc objetos fuera del servicio y, a continuación, presentar en el servicio…
    • Tengo que hacer un plan para mover a MVC, pero tratando de conseguir mi cabeza alrededor de algunos de los fundamentos de la arquitectura como he básicos de formularios web forms de la experiencia y sólo puede tomar tanto a la vez.
    • Tanto los ejemplos de código de mirar bien, excepto por GiftCertificate gc = new GiftCertificate(); he mencionado en mi respuesta no debería ser crear instancias para hacer la validación. Echa un vistazo a S#arp tienen completa de soluciones de código que usted puede mirar a través.
    • Voy a retirar S#arp para obtener algunas ideas. Cuando usted dice que yo no debería instancia de validación, cómo en la capa de interfaz de usuario puedo acceder a mi modelo/entidad métodos de validación? Hacen estática? eg – IsValidCode
    • Me encanta tu respuesta, pero no has contestado a una de las preguntas lo suficientemente bien, que es «además De la capa de servicio, debe haber también una separada capa de lógica de negocio, o es que la función de la capa de servicio?» también son la capa de negocio y capa de servicio de la misma cosa ?
    • +1 Gran Respuesta!
    • Todo este S#arp estilo de Arquitectura de la aplicación es un gran código de olor. Pasar a través de métodos son inútiles, y añadir un extra de sentido de la capa de abstracción. 1:1 de los servicios a los repositorios va en contra de Domain Driven Design (DDD), que es normalmente cuando se utiliza el modelo de Repositorio. Hay mejores y más enfoques pragmáticos. Los invito a mirar en DDD más de cerca, así como cosas como el uso de CQS (Comando de Consulta de Separación) y un contenedor de DI.

  2. 3
    1. Usted no tiene que crear el repositorio por entidad,ver aquí para más,

      Generalmente uno define un repositorio por
      agregado en el dominio. Que es:
      no tiene un repositorio por entidad! Si
      tenemos un vistazo a una simple orden de entrada
      el sistema de la entidad, podría ser el
      raíz de un Pedido agregado. Así nos
      tendrá un Repositorio de pedidos.

    2. Debe ser un servicio al repositorio? -> No siempre, ya que puede utilizar los repositorios múltiples en uno de los servicios.

    3. Servicio, se crea el Modelo de instancia, repositorio nunca va a interactuar con el Modelo, de hecho, se devuelve a la Entidad el modelo que utilizará posteriormente.

    4. Controlar la Entrada/etc tipo de validación a nivel de UI(u puede utilizar javascript o cualquier otra biblioteca), y permitir que los Servicios de manejar sólo los aspectos del negocio. Usted puede obtener los beneficios de los Atributos que se hace de la misma.

    5. UI->Servicio->Repositorio, si el repositorio es el servicio de llamadas de thr debe estar algo mal de la OMI.


    Que los cambios de código,

    1. Hacer de Modelo y de los Repositorios separados.

      public class GiftCertificateModel
      {
      }
      public class GiftCertificateRepository
      {
         //Remove Model related code from here, and just put ONLY database specific code here, (no business logic also). Common methods would be Get, GetById, Insert, Update etc. 
      
          Since essence of Repository is to have common CRUD logic at one place soyou don't have to write entity specific code. 
          You will create entity specific repository in rare cases, also by deriving base repository.
      
      }
      
      public class GiftCertificateService()
      {
          //Create Model instance here
          //Use repository to fill the model (Mapper)
      
      }
    • cuando dices «3.El servicio crea el Modelo de instancia, repositorio nunca va a interactuar con el Modelo, de hecho, se devuelve a la Entidad el modelo que utilizará posteriormente.» ¿Cuál es la diferencia entre el modelo y la entidad? Ahora mismo tengo Servicio/Repositorio/POCO. El repositorio agarra los datos y las llamadas de un mapper que se asigna a mis POCOs (Dominio de objetos/entidades/lo que sea). Estás diciendo que el servicio debe ser la creación de nuevos vacío entidades cuando tengo que hacer uno nuevo? Algún consejo sobre mi pasado 2 ejemplos de código?
    • Entidad que está relacionada con la base de datos(repositorio) y en el modelo de aquí que se adjunta a la interfaz de usuario. Así, su enfoque es correcto, excepto que me refiero Servicio de llamada repositorio para llenar/insertar/actualizar datos y la interfaz de usuario va a interactuar con el Servicio. Así repositorios nunca va a interactuar con la interfaz de usuario directamente. (Separación de Preocupación)
    • gotcha! Nuevos certificados de regalo requieren un código especial que debe ser generados y controlados por la singularidad en la base de datos. Debe mi interfaz de usuario de crear el nuevo certificado de regalo de la entidad y obtener el código de servicio de la capa, a continuación, llame a servicio para guardar O simplemente llame al servicio de la capa, que devolverá un nuevo certificado de regalo de objeto con el código que ya está llena O si la interfaz de usuario llama a un método en el servicio para crear nuevo que toma parámetros de cantidad, expDate y hace todo lo que crean objetos, obtener el código, guardar en la base de datos y pasar de nuevo objeto completo en un solo paso?
    • Ok,en tal caso, la primera consulta para el código de la singularidad, si es exclusivo de hacer los pasos correspondientes, como ahorrar o conseguir. También Si ur interfaz de usuario no necesita que el código que paso de todo, otra cosa generar primero de usarlo y pasar los valores, para la modificación.
    • Re: #4, no son los campos que son necesarios para la compra de una tarjeta de regalo definido por el negocio, y por lo tanto el acceso de las empresas? ¿Qué pasa si usted quiere construir un WP7 aplicación que permite a los mismos casos de uso, no esta sugerencia significa que usted tiene que recodificar que la validación de nuevo en la interfaz de usuario de WP7? Lo que sobre SECO?
    • que es parte de mi pregunta. Creo comunes validaciones deben ser parte de la lógica de negocio.
    • sí correcto, y aquí quiero decir que el nivel de UI de validación se repite porque la interfaz de usuario podría ser MVC donde los Ayudantes HTML/ JQuery validaciones que se puede hacer, en ASP,Net uno puede usar el campo requerido validadores. Lo que si tenemos WCF llamada de podemos no se necesitan estas validaciones como cliente puede optar por otro camino. Por lo tanto su su llamada. Pensar en la manera que ¿por qué solicitar un golpe en el servidor que puede ser manejado en la interfaz de usuario de la misma?

  3. 0

    Puede crear un servicio llamado GiftCertificateService.

    De que manera se va a coordinar cualquier tarea que no pertenecen a la responsabilidad de la GiftCertificateModel en su servicio. (No debe confundirse con un servicio de WCF).

    El servicio de control de todas las tareas de modo que su interfaz de usuario (o cualquier persona que llama que podría ser), se usan los métodos definidos en el servicio.

    El servicio, a continuación, llamar a métodos en el modelo, de utilizar el repositorio, crear transacciones, etc.

    De ex. (basado en el código de ejemplo que se proporciona):

    public class GiftCertificateService 
    {
       public void CreateCertificate() 
       {
          //Do whatever needs to create a certificate.
          GiftCertificateRepository gcRepo = new GiftCertificateRepository();
          GiftCertificateModel gc = gcRepo.CreateNew();
          gc.Amount = 10.00M;
          gc.ExpirationDate = DateTime.Today.AddMonths(12);
          gc.Notes = "Test GC";
          gcRepo.Save(gc);
       }
    }

    La interfaz de usuario se llame a la CreateCertificate método (paso de argumentos, etc) y el método puede devolver algo también.

    NOTA: Si desea que la clase a actuar en la interfaz de usuario, aunque, a continuación, crear una clase de controlador (si usted está haciendo MVC) o una clase de moderador (si usted está haciendo MVVM, y no quiero poner todo dentro de la ViewModel) y el uso de la GiftCertificateService de esa clase.

    • Estoy usando formularios web con ADO clásico para la interacción de base de datos. Así que, ¿es necesario crear todas las mismas propiedades en el servicio como el que tengo en mi modelo de cantidad, fecha de caducidad, etc? Y sólo para aclarar, nunca se me va a llamar de nuevo repo, o el nuevo modelo de la interfaz de usuario, pero sólo a partir de la capa de servicio.. por ejemplo GiftCertificate gc = GiftCertificateService.NewGiftCertificateObject(), a continuación, complete el objeto y llamar al servicio de métodos save?
    • Si usted está usando formularios web forms la mayoría de las ocasiones son sus puntos de vista son autónomas con controladores de eventos o de seguir un modelo-vista-x patrón (moderadores o controlador). Los controladores de eventos o controladores/presentadores son el lugar adecuado donde se puede llamar a métodos en los servicios (incluso realizar el acceso a los datos, aunque la mayoría de las directrices de desalentar este). No es necesario crear todas las mismas propiedades. Usted puede agregar un reutilizables capa en la parte superior (que es un servicio aquí) y desde allí llamar a métodos que coordine las acciones (acceso a datos, validación, las llamadas a los objetos del modelo, etc).

Dejar respuesta

Please enter your comment!
Please enter your name here