Pregunta

Estoy utilizando el patrón de repositorio genérico para persistir mis datos. Por pageLoad, estoy creando un nuevo repositorio (de IRepository) objeto, y en PageUnload, me deshago de ella.

Si el MasterPage / Página a cargo de crear instancias de los objetos para pasar al presentador o presentadora debería ser el responsable de esto? Estoy más preocupado con la prueba de que el presentador de la página (Vista), ya que es más fácil para burlarse de las interfaces que se pasan al presentador.

Ejemplo de página

public partial class _Default : System.Web.UI.Page
{
    private IRepository _repo;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (_repo == null)
            _repo = new Repository();
        ConnectPresenter();
    }

    private void ConnectPresenter()
    {
        _DefaultPresenter presenter = new _DefaultPresenter(_repo);
    }

    private void Page_Unload(object sender, EventArgs e)
    {
        if (_repo != null)
            _repo.Dispose();
    }
}

¿Un marco DI como StructureMap o ayuda Ninject en este caso? ¿Sería el encargado de desechar objetos como este?

¿Fue útil?

Solución

Ni la clase de página ni los presentadores deberían tener que tratar directamente con la gestión de la construcción o del ciclo de vida de cualquiera de sus dependencias - que deben ser manejados por el contenedor. Dado que la inyección de constructor no funciona con formularios Web, tendrá que exponer a las dependencias necesarias como propiedades en la clase. Por ejemplo, usted podría cambiar su clase a:

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }

    public _DefaultPresenter Presenter { get; set; }
}

La página no debería necesitar ninguna referencia al repositorio, ya que se inyecta en el presentador.

El resto de esta respuesta es específica para StructureMap - detalles pueden ser diferentes para otros recipientes

.

Para permitir la inyección de setter, es necesario contar StructureMap qué propiedades para poblar. Una forma es aplicar el atributo [SetterProperty] a la propiedad en sí. Sin embargo, esto puede sentir un poco invasivo para tener detalles StructureMap dentro de sus clases. Otra forma es configurar StructureMap para que sepa qué tipo de propiedad para inyectar. Por ejemplo:

protected void Application_Start(object sender, EventArgs e)
{
    ObjectFactory.Initialize(x =>
    {
        x.Scan(scan =>
        {
            scan.TheCallingAssembly();
            scan.WithDefaultConventions();
        });
        x.ForRequestedType<IRepository>().TheDefaultIsConcreteType<Repository>().CacheBy(InstanceScope.Hybrid);
        x.SetAllProperties(set => set.WithAnyTypeFromNamespaceContainingType<IRepository>());
    });
}

El método SetAllProperties permite indicar a StructureMap cómo reconocer las propiedades que debe rellenar. En este caso, yo estoy diciendo StructureMap para inyectar todos los presentadores (suponiendo que todos están en el mismo espacio de nombres).

Todavía es necesario realizar la inyección colocador en cada petición. Con StructureMap, se utiliza el método de acumulación () para inyectar dependencias en la instancia existente. Se podía hacerlo en los eventos Init o la carga de cada página o una página de clase base, pero de nuevo, que se siente invasivo. Para mantener el recipiente fuera de sus clases de página por completo, se puede utilizar el evento PreRequestHandlerExecute de la aplicación (en Global.asax o un IHttpModule):

protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
    var application = (HttpApplication)sender;
    var page = application.Context.CurrentHandler as Page;
    if (page == null) return;
    ObjectFactory.BuildUp(page);
}

Por último, si desea deshacerse de forma explícita su IRepository, se podía manejar que en el caso EndRequest:

protected void Application_EndRequest(object sender, EventArgs e)
{
    var disposable = ObjectFactory.GetInstance<IRepository>() as IDisposable;
    if (disposable != null) disposable.Dispose();
}

Tenga en cuenta que esto funciona correctamente porque en la inicialización le dijimos StructureMap para almacenar en caché por IRepository híbrido, que significa "dame la misma instancia para cada solicitud HTTP (o hilo, si no se ejecuta dentro de una página web)". Al recuperar la IRepository en EndRequest, recibirá el mismo que se utiliza en toda la solicitud, y usted puede deshacerse de él.

Otros consejos

Sí, sería bien vale la pena que la investigación los tutoriales por ahí de la utilización de DI con ASP.NET .

Sí, Eliminación del comportamiento por Solicitud objetos en el punto apropiado es generalmente administrado por la integración del contenedor con ASP.NET.

La disposición típica es que la creación de flujos de objeto desde la página y Application / Module S hacia el interior. Generalmente se marca propiedades [Inject] en su Page clase, pero depende de cómo se ha organizado su tríada. El presentador puede utilizar generalmente Constructo de inyección para declarar lo que necesita, independientemente de si su prueba o ASP.NET cotexto. A continuación, en tiempo de ejecución, las dependencias serán satisfechas por el DI. Al tiempo de la prueba, aún puede utilizar DI, aunque en otros casos podría ser más natural que acaba de crear un montón de falsificaciones junto con el SUT y pasar los al presentador.

En cuanto a los arreglos triead prueba WRT, encontré este artículo de MSDN sobre el uso de Mag Ninject con xUnit.net por Justin Etheredge muy útil, aunque su dirigidos a ASP.NET MVC.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top