14

Estoy al principio del desarrollo de un nuevo proyecto ASP.Net MVC y estoy usando este proyecto para entrar en DI. Estoy bastante seguro de que voy a ir con Structure Map, pero eso no es lo que estoy preguntando. Lo que trato de descubrir es la mejor forma de organizar mi solución. ¿El proyecto de prueba de la unidad y el modelo obtienen un archivo de configuración para mapear sus dependencias o hay una clase para gobernarlos todos?¿Cuál es la mejor forma de organizar una solución ASP.Net MVC mediante inyección de dependencia?

Además, ¿hay alguna trampa para novatos que evitar antes de llegar demasiado lejos en esto?

Muchas gracias, ..... Todo

actualización debo añadir que cuando digo "organizar la solución", no me refiero al número de archivos/carpetas, etc., sino más bien cómo estructurar las clases que están involucradas con DI. En particular, cómo administrar el bootstrapper. Puedo ver que un pobre fraseo de mi parte podría causar confusión.

+1

Mi trampa para principiantes con StructureMap eran las excepciones de permisos de seguridad en Medium Trust. Debería buscar en un contenedor DI alternativo si su aplicación se ejecutará en entornos de confianza media. –

Respuesta

2

Para fomentar una mejor TDD. Tener dos proyectos de prueba y/o nombres X.Unit.Tests & X.Integrations.Tests.

Tengo mi código DI en mi proyecto principal en un "directorio de espacio de nombre" (/ Config) pero en mis pruebas de código de integración, podría simplemente llamar a esos registros o anular si requiriera en mis accesorios o configuraciones básicos.

E.g.

/Config/ServiceRegistry.cs /Config/RepositoryRegistry.cs /Config/Bootstrapper.cs

En Global.asax que llamo Bootstrapper.Init() y esto exigirá x.AddRegistry (nueva ServiceRegistry ()) y así.

En mis pruebas de unidad no es necesario que use DI solo en sus pruebas de integración. En mis IntegrationTests, p. Ej. si estoy probando NHibernate a través de la base de datos, podría inicializar SM con RepositoryRegistry en TestSetUp con un método auxiliar que solo envolviera GetInstance().

No me divido en proyectos .Bootstraper y .Domain hasta que tenga absolutamente que ... Tres proyectos, X, X.UnitTests, X.Integration si requirió más movimiento más tarde. Vengo de una organización de base/de la empresa de tener docenas de proyectos que creí que era una primera reducción, pero ahora no, voy a ir a la etapa de crecimiento rápidamente y reorganizo la estructura de las soluciones más adelante si es necesario.

10

Si usted es el único que trabaja en el proyecto, yo haría lo que tiene sentido para usted primero. No hay nada peor que tener una estructura de directorio o proyecto impuesta sobre ti que no te resulte intuitiva. ¿Está la clase BaseController en la carpeta \ Core \ o en la carpeta \ Controller \? Personalmente miraría en el Controlador pero algunas personas juran que debería estar en \ Core \ o \ Bases.

La primera trampa para principiantes está pensando que puede organizar su código de forma incorrecta y de alguna manera esto se refleja en el éxito del proyecto. He visto proyectos en los que había 30 archivos en una carpeta y otros proyectos en los que había 20 carpetas para 30 archivos.

La segunda trampa para novatos olvida que, en comparación con otros idiomas, tiene la ventaja de contar con intellisense, herramientas de navegación de código y compatibilidad con refactorización de Visual Studio. También tiene un compilador que hace que extraviar un archivo sea menos doloroso. Si coloca algo en el lugar "incorrecto", está bien, siempre puede encontrarlo y arrastrarlo hasta donde debe estar.

Seré honesto Estoy trabajando en un proyecto en este momento y no estoy seguro de dónde residen ciertas clases en mi estructura de archivos. Ir a Definición/Declaración son atajos de teclado que uso mucho. Debido a que solo yo estoy trabajando con el código, esto está bien. Si tuviera que agregar otro desarrollador en el proyecto, probablemente debería limpiar las cosas.

Personalmente tiendo a poner Interfaces con sus tipos de implementación dentro de la misma carpeta. IPaymentGateway está en la misma carpeta que AuthorizeNetGateway y PaypalGateway. Si no puedo ver todos los archivos en esa carpeta a la vez en la barra lateral de mi explorador de soluciones, muevo todos los archivos de Gateway a una carpeta \ Gateway \.

Con Dependency Injection agregado a la mezcla, le aconsejo que solo se preocupe por las explosiones del espacio de nombres. Lo peor que puedes hacer es desordenar tus bootstrappers y archivos con declaraciones y alias largos.

ForRequestedType<Customer> 

es más limpio que

using KevDog.Models 
using Customer=KevDog.Models.Customer 

o

ForRequestedType<KevDog.Models.Customer> 

Otra forma de evitar este problema es ser explícita cuando su nombre a las cosas: al cliente, CustomerViewModel, CustomerController, CustomerDataRow, CustomerView

Para TDD casi tiene que tener dos bootstrappers para administrar tus tipos concretos Realmente no desea que sus pruebas unitarias utilicen AuthorizeNetGateway: IPaymentGateway, sino StubGateway: IPaymentGateway.

Ahora también soy nuevo en DI, por lo que tiendo a hacer las cosas muy simples y reflejar los 101 niveles de tutoriales y documentación. Entrar en la inyección dinámica en función de una configuración de compilación solo debe utilizarse cuando una situación específica lo requiera y sepa exactamente por qué lo hace.

Por lo general, también conservo la estructura predeterminada para las aplicaciones MVC. Es simplemente más fácil tener tu código en la misma estructura que el 99% de todos los tutoriales y videos.

Espero que esto ayude.

+0

Gracias jfar! El comentario sobre TDD es realmente el tipo de cosas sobre las que quería preguntar. Creo que la idea de un arranque para cada proyecto es el camino a seguir. Uno en el proyecto de prueba de unidad y uno en el proyecto de MVC – KevDog

0

Este es mi primer intento de resolver el mismo problema para mí, pero dado que es mi primer intento, espero que la gente lo comente o lo critique tanto como desearía que pudiera servir como una posible solución para que:

public VatManager() 
: this(new VatManagerRegistry()) { } 

public VatManager(Registry registry) 
: this(new Action<IInitializationExpression>(x => { x.AddRegistry(registry); })) 
    { 
    } 

public VatManager(Action<IInitializationExpression> action) 
    { 
    ObjectFactory.Initialize(action); 
    data = ObjectFactory.GetInstance<IVatManagerData>(); 
    } 

tengo tres sobrecargas del constructor - el constructor predeterminado sin parámetros tiene conocimiento del registro StructureMap concreto que tiene que ser creado para su uso en un contexto de producción.Los otros dos permiten otro código que ejemplifica esta clase de administrador para proporcionar sus propios registros o acciones de StructureMap para que puedan controlar las inyecciones de dependencia, como en el caso de una prueba automatizada que proporciona simulaciones en lugar de instancias concretas de esas dependencias. Debo añadir que esta solución no es particular de un contexto ASP.NET MVC y no extrae ninguna información de configuración de los archivos * .config.

Cuestiones relacionadas