2010-02-17 16 views
9

En mi aplicación ASP.NET MVC, tengo un proyecto que contiene toda la lógica de negocios/capa de servicio. Este proyecto interactúa con mi base de datos (Entity framework) que se encuentra en un proyecto separado.Capa de servicio de aplicación como clases estáticas

Quería acceder fácilmente a la capa de servicio, así que creé clases estáticas en ella para que puedan ser referenciadas fácilmente. Por ejemplo, si estoy en mi controlador y tengo que crear una nueva cuenta:

ServiceLayer.Accounts.CreateAccount(userName, passWord) //etc.. 

La capa de servicio, entonces no toda la lógica necesaria, a continuación, crea el usuario a través del repositorio en el DatabaseLayer.

private static AllRepos _Repos; 
    private static AllRepos Repos { 
     get 
     { 
      if(_Repos == null) 
       _Repos = new AllRepos(); 

      return _Repos 
     } 
    } 

    public static void CreateAccount(string username, password) 
    { 
     string salt = GenerateSalt(); 
     Account newAccount = DatabaseLayer.Models.Account 
       { 
       Name = username, 
       Password = HashPassword(password, salt), 
       Salt = salt 
       }; 
     Repos.AddAccount(newAccount);  
    } 

Debido a que no quería hacer lo siguiente en todas partes en mi capa de servicio:

AccountRepository Accounts = new DatabaseLayer.AccountRepository(); 

en lugar de eso creado una clase contenedora para mis repositorios de manera que no tengo más que una instancia de una vez para usar todos los otros repositorios

public class AllRepos 
{ 

    private AccountRepository _Accounts; 

    public AccountRepository Accounts 
    { 
     get 
     { 
      if (_Accounts== null) 
       _Accounts= new AccountRepository(); 

      return _Accounts; 
     } 
    } 

    // the same is done for every other repository (currently have about 10+) 
    } 

Que se usó en las clases estáticas de la capa de servicio.

Dado que todas mis clases de capa de servicio son estáticas y el campo Repos también es estático, el problema obvio que sigo encontrando es cuando el mismo objeto se recupera de múltiples contextos de datos causando comportamientos extraños para las actualizaciones/eliminaciones.

Entiendo que esto es de esperar si uso miembros/clases estáticos como lo hice, ya que duran el ciclo de vida de la aplicación, pero ¿hay alguna manera de poder utilizar la capa de servicio como ServiceLayer.Accounts.Method() sin tener que crear una clase no estática que necesita ser instanciada donde sea que se use y no encontrarse con los problemas de CRUD debido a múltiples instancias de contextos de datos?

+0

"de hecho, algunos de los mejores métodos de ayuda son estáticos" ¿Cuál es su concepto de "mejor"? –

Respuesta

15

Su enfoque para esto realmente no es recomendable. Personalmente, nunca permitiría este tipo de enfoque en mi equipo. Los inconvenientes:

  1. principales problemas de threads, como que está experimentando, que no son fáciles de resolver
  2. No se puede probar esta muy fácilmente en absoluto.
  3. abstracción poco realistas de sus datos de acceso

La razón más importante para la creación de instancias de repositorios es por lo que se puede inyectar las dependencias si es necesario. El argumento más conocido para esto es la prueba unitaria para que pueda burlarse de las dependencias, pero he creado varios repositorios que tienen dependencias de interfaz que cambian en el código de producción.

Simplemente debe hacer su instancia de repositorio como parte de sus clases de servicio base de todos modos.No hay ninguna razón para que tenga que ser "estática O llamadas de instancia en todas partes". Debería haber un código de instanciación de instancia limitado dentro de las clases base.

+0

También me gustaría añadir que he tenido problemas para escalar a MSDTC cuando uso una clase estática entre el controlador y el servicio – DevDave

10

No estoy seguro de por qué está tan inactivo frente al uso de instancias. Aparte del hecho de que el código que tiene ahora es innecesariamente complicado, el uso de tipos estáticos también dificulta la prueba unitaria. El tipo estático es como un singleton que no puedes simular ni reemplazar. Me parece que su verdadera pregunta podría ser: "¿Cómo manejo las instancias de mi capa de servicio de por vida?" Normalmente, lo hace teniendo una instancia por solicitud web. En una aplicación ASP.NET MVC, puede new up a DI container via a ControllerFactory, and handle all of this. [PDF]

1

que necesita para manejar el alcance de su ObjectContext de una manera deliberada, como hacer un Unit Of Work pattern

Aparte de eso, yo creo que deberías reconsiderar haciendo todo lo estático, como womp dice usted consigue muy alto acoplamiento, y hace que sea muy difícil de probar, y puede obtener mucha ayuda con la gestión del gráfico de dependencia mediante el uso de un contenedor IOC.

puedo decir que, después de haber quemado a mí mismo haciendo ese tipo de cosas previamente :)

-3

Singleton (y clases estáticas como se describe) son el mal y debe ser evitado a toda costa, especialmente en aplicaciones web.

+0

no estoy de acuerdo con eso, los métodos de Helper son ideales cuando estático. De hecho, algunos de los mejores métodos de ayuda son estáticos para uso web. Solicitud, Server.MapPath, Archivo/Directorio, etc. – Mike

Cuestiones relacionadas