1

Ich habe die Klassen unter:Unity Lösung nicht Repository

SuppliersRepository.cs (mit der Schnittstelle des Verfahrens definiert wurden):

public class SuppliersRepository : BaseRepository,ISuppliersRepository 
    { 
     public IEnumerable<Supplier> GetSuppliersByCoordinates(double latitude, double longitude) 
     { 
      using (IDbConnection connection = OpenConnection()) 
      { 
       const string query = "SELECT ID=SupplierID,Name=Suppliername FROM suppliers WHERE dbo.Distance(@latitude,@longitude,latitude,longitude) < 15 AND latitude IS NOT NULL AND longitude IS NOT NULL"; 
       return connection.Query<Supplier>(query, new { latitude = latitude,longitude=longitude }); 
      } 
     } 

    } 

BaseRepository.cs (mit der Schnittstelle des Verfahrens definieren,

)
public abstract class BaseRepository: IBaseRepository 
{ 
    public IDbConnection OpenConnection() 
    { 
     IDbConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["myconnection"].ConnectionString); 
     connection.Open(); 
     return connection; 
    } 

}

A Bootstraper.cs von global.asax.cs callte mit:

public static class Bootstrapper 
    { 
     public static void Initialise() 
     { 
      var container = BuildUnityContainer(); 

      DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 
     } 

     private static IUnityContainer BuildUnityContainer() 
     { 
      var container = new UnityContainer(); 

      container.RegisterType<IBaseRepository, BaseRepository>(); 
      container.RegisterType<ISuppliersRepository, SuppliersRepository>(); 
      container.RegisterInstance<IHttpControllerActivator>(new HttpControllerActivator(container)); 
      container.RegisterControllers(); 


      return container; 
     } 
    } 

Und zwei Controller löst erste das Repository fein:

public class VenueController : MasterController 
    { 
     [Dependency] 
     public SuppliersRepository _SuppliersRepository { get; set; } 
    } 

Aber dieser ausfällt:

public class AjaxController : Controller 
    { 
     [Dependency] 
     public BaseRepository _BaseRepository { get; set; } 
} 

Es wirft eine System.InvalidOperationException: Der Typ BaseRepository kann nicht erstellt werden. Sie müssen den Container konfigurieren, um diesen Wert zu liefern.

Irgendeine Idee was mache ich falsch?

+0

Es ist besser, die Konstruktorinjektion anstelle der Eigenschaftsinjektion zu verwenden. Auf diese Weise müssen Sie Ihre Eigenschaften nicht mit dem Attribut "[Dependency]" dekorieren und verhindern, dass Ihr Anwendungscode eine Abhängigkeit von Unity erhält. – Steven

Antwort

2

Zunächst ist es bei Verwendung der Abhängigkeitsinjektion besser, Abhängigkeiten von Schnittstellen zu haben, als Abhängigkeiten von konkreten Klassen zu haben. Ich würde Ihre Controller

public class VenueController : MasterController 
{ 
    [Dependency] 
    public ISuppliersRepository _SuppliersRepository { get; set; } 
} 


public class AjaxController : Controller 
{ 
    [Dependency] 
    public IBaseRepository _BaseRepository { get; set; } 
} 

zweite Änderung, BaseRepository ist abstract Klasse. Instanzen der abstrakten Klasse können nicht konstruiert werden, und ich denke, das ist der Grund, warum es versagt, wenn die Einheit zur Schaffung von BaseRepository führt. Sie sollten konkrete Klassen injizieren.

container.RegisterType<IBaseRepository, SomeConcreteImplementationOfBaseRepository>(); 
+0

+1 BaseRepository ist in der Tat abstrakt. – StuartLC

+0

Danke dafür, ich war faul und ich habe die Methode in meinem BaseRepository hinzugefügt und wenn nicht konstruiert werden kann abstrakt sein, dann verschiebe ich die Methode in eine andere Klasse basierend auf BaseRepository und es funktioniert jetzt gut. –

0

Sie sollten Ihre Klassen definieren eine Eigenschaft von IRepository zu nehmen, zum Beispiel:

public class AjaxController : Controller 
{ 
     [Dependency] 
     public IRepository _BaseRepository { get; set; } 
} 

Ihre Eigenschaften immer in Bezug auf die Schnittstelle definiert werden sollte, nicht die konkrete Umsetzung, sonst haben Sie sich auf die Umsetzung gebunden , wodurch die Verwendung der Abhängigkeitsinjektion eher sinnlos wird!

+0

Gut genug, ich habe ursprünglich die Schnittstelle injiziert, aber ich habe das geändert, weil es nicht funktionierte und keine Ideen mehr hatten! –

+0

@RB - Obwohl Sie Recht haben, dass DI in der Regel mit der Schnittstellentrennung verwendet wird, könnte OP Unity verwenden, um ein abgeleitete SuppliersRepository in eine beliebige BaseRepository-Eigenschaft zu injizieren, also container.RegisterType (); – StuartLC