5

estoy tratando de utilizar la unidad para inyectar automáticamente una DataContext en mi repositorio usando una nueva instancia cada vez .., mi idea es el asegurar que cada vez que un nuevo DataContext se inyectaUNIDAD: ¿se pasa un nuevo contexto de datos cada vez?

Actualmente su defecto en la creación del repositorio, creo que no puede resolver MyDataContext

Antes de crear un constructor en "el repositorio" (véase más adelante) para tomar en el DataContext en mi repositorio todo funcionaba pero ahora su defecto ..

Actualmente tengo esta configuración en mi contenedor de unidad que creo en global.asax, también he registrado el tipo MyDataContext que es DataContext estándar

 container = new UnityContainer(); 

     Container.RegisterType<MyDataContext, MyDataContext>() 
      .RegisterType<IOfficeRepository, OfficeRepository>() 
      .RegisterType<IOfficeService, OfficeService>(); 

básicamente tengo un servicio que llama al repositorio al igual que

public class OfficeService : IOfficeService 
{ 

    IOfficeRepository repository = null; 

    public OfficeService(IOfficeRepository repository) 
    { 
     this.repository = repository; 

     if (this.repository == null) 
      throw new InvalidOperationException("Repository cannot be null"); 
    } 

aquí está mi repositorio

public class OfficeRepository : IOfficeRepository 
{ 
    private MyDataContext db; 

    public OfficeRepository (MyDataContext dataContext) 
    { 
     this.db = dataContext; 
    } 

EDITAR

casi me olvido que estoy haciendo esto para crear el servicio

officeService = Bootstrapper.Container.Resolve<IOfficeService>(); 

EDITAR - EL ERROR está generando

Resolution of the dependency failed, type = "MarkSmith.IOfficeService", name = "". 
Exception message is: The current build operation (build key Build 
Key[MarkSmith.OfficeService, null]) failed: The parameter repository could not be 
resolved when attempting to call constructor 
MarkSmith.OfficeService(MarkSmith.IOfficeRepository repository). (Strategy type BuildPlanStrategy, index 3) 

EDITAR - EXTRACCIÓN Constructor en el repositorio de obras

Es algo que ver con el DataContext porque si quito el constrcutor en el repositorio que toma un DataContext luego todo funciona, pero por supuesto necesito que acepte un DataContext para poder inyectar un "nuevo" contexto de datos cada vez

public class OfficeRepository : IOfficeRepository 
{ 
    private MyDataContext db new MyDataContext(); // CHANGE 

    //public OfficeRepository (MyDataContext dataContext) 
    //{ 
     //this.db = dataContext; 
    //} 

EDITAR - error real

Después de cavar más profundo que he encontrado este error ....

The type MyDataContext has multiple constructors of length 2. 
Unable to disambiguate. (Strategy type DynamicMethodConstructorStrategy, index 0) 
(Strategy type BuildPlanStrategy, index 3) 

EDITAR - TEST PARA RESOLVER EL DataContext con 1 línea de código

Esto también falla con el mismo error que el anterior - múltiples constructores

MyDataContext test = Bootstrapper.Container.Resolve<MyDataContext >(); 

EDITAR - todos los constructores EN MI DataContext

estos fueron creados por un util exernal pero todos deben estar bien ..

[System.Diagnostics.DebuggerNonUserCode] 
    public MyDataContext() 
     : base(ConnectionString, mappingCache) 
    { 
     OnCreated(); 
    } 

    [System.Diagnostics.DebuggerNonUserCode] 
    public MyDataContext(string connection) 
     : base(connection, mappingCache) 
    { 
     OnCreated(); 
    } 

    [System.Diagnostics.DebuggerNonUserCode] 
    public MyDataContext(System.Data.IDbConnection connection) 
     : base(connection, mappingCache) 
    { 
     OnCreated(); 
    } 

    [System.Diagnostics.DebuggerNonUserCode] 
    public MyDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) 
     : base(connection, mappingSource) 
    { 
     OnCreated(); 
    } 

    [System.Diagnostics.DebuggerNonUserCode] 
    public MyDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) 
     : base(connection, mappingSource) 
    { 
     OnCreated(); 
    } 

EDITAR - Para demostrar la creación de la DataContext en el código sin la unidad funciona al 100% sin ningún problema

MyDataContext tes2t = new MyDataContext(); 
+0

Pregunta actualizada para mostrar cómo estoy resolviendo mi servicio usando la unidad –

+0

¿Qué sucede si intentas resolver una instancia de MyDataContext usando en varios puntos? Todo parece estar en orden, pero eso puede darnos una pista. – GraemeF

+0

Además, ¿falta una línea o un error ortográfico en el primer extracto del código? Parece que 'container' y' Container' serían instancias diferentes. Puede verificar que tiene la instancia que espera utilizando el depurador. – GraemeF

Respuesta

10

no estoy seguro de que esto funciona, pero ¿ha intentado registrar MyDataContext como un componente en lugar de un mapeo de tipo?

container.RegisterType<MyDataContext>(); 

en lugar de

container.RegisterType<MyDataContext, MyDataContext>(); 

EDITAR basada en la nueva información

El culpable parece ser que MyDataContext tiene más de un constructor. Este es un problema común con la mayoría de los Contenedores DI, ya que necesitan elegir y usar solo uno. Si puede eliminar la ambigüedad al obligar a MyDataContext a tener solo un constructor, esa será probablemente la solución más simple.

De lo contrario, debería poder usar una instancia de InjectionConstructor para identificar el constructor cuando se registra el repositorio. Supongamos que usted quiere utilizar un constructor que toma una cadena de conexión como argumento:

string connectionString = 
    ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString; 
var injectedConnectionString = new InjectionConstructor(connectionString); 
container.RegisterType<MyDataContext>(injectedConnectionString); 
+0

Gracias Mark, lo intenté y es lo mismo. He actualizado mi pregunta con el error específico .. –

+0

Pregunta actualizada también para mostrar la eliminación de obras del constructor, pero, por supuesto, necesito que el constructor acepte un DataContext, ¿alguna idea? –

+0

Ver mi respuesta actualizada. –

1

no veo sus constructores MyDataContext; pero intente agregar el atributo [InjectionConstructor] al que desea usar.

+1

Eso debería funcionar, pero unirá estrechamente MyDataContext a Unity. –

+0

¡Este hecho realmente funciona! Pero como señala Mark, está estrechamente acoplado y también mi contexto de datos es creado por una utilidad externa por lo que el atributo se sobrescribe ... Realmente no entiendo completamente por qué la unidad tiene un problema, no estoy interesado en ningún constructor (es decir, constructores con 2 aprams) solo estoy interesado en el constructor de cero param y, por supuesto, solo hay 1 ... ¿Hay alguna alternativa? –

3

Con múltiples constructores para elegir, Unity no sabe cuál usar. Elegirá el que tenga más argumentos que todos puedan satisfacer, pero en este caso hay dos constructores, cada uno con dos argumentos que se pueden resolver.

Si no desea que su pareja de clase MyDataContext a la Unidad y utiliza el atributo InjectionConstructor según lo sugerido por Scott (upvoted :)), puede especificar el constructor que se debe utilizar en el momento de la inscripción mediante el interfaz fluida . Vea Configuring Constructor, Property, and Method Injection para más detalles.

+0

Gracias GraemeF, esta es una gran información .. Gracias por toda su ayuda .. –

Cuestiones relacionadas