1

我使用域中心architecture.I創建asp.net應用程序有因爲依賴注入無法應用層的問題Demeter.Application.Events.Queries.QueryEvent.GetEventsListQuery 解決Demeter.Application.Interfaces.IDatabaseService。有人可以幫助我解決依賴注入?IDatabaseService依賴項注入失敗?

System.InvalidOperationException:無法解析類型 'Demeter.Application.Interfaces.IDatabaseService' 服務,同時試圖 激活 'Demeter.Application.Events.Queries.QueryEvent.GetEventsListQuery'。

namespace Demeter.Application.Events.Queries.QueryEvent 
{ 
    using System.Collections.Generic; 
    using Commands.CreateEvent; 
    using Demeter.Application.Interfaces; 
    using AutoMapper; 
    using Domain; 


    public class GetEventsListQuery : IGetEventsListQuery 
    { 
     public List<ListEventModel> Execute() 
     { 
      var events = this.databaseService.SelectEventsForList(); 

      //// Use AutoMapper to convert events (IEnumerable<Event>) to (List<ListEventModel>) 
      //IMapper mapperConfig = this.mapperConfig.CreateMapper(); 

      //return Mapper.Map<IEnumerable<Event>, List<ListEventModel>>(events); 
      return null; 
     } 

     public GetEventsListQuery(IDatabaseService databaseService) 
     { 
      this.databaseService = databaseService; 
      //TO-DO: Move this to mapper congigfration function 
      //this.mapperConfig = new MapperConfiguration(cfg => { 
      // cfg.CreateMap<Event, ListEventModel>(); 
      //}); 
     } 

     private readonly IDatabaseService databaseService; 
     private readonly MapperConfiguration mapperConfig; 

    } 
} 

namespace Demeter.Application.Interfaces 
{ 
    using System.Collections.Generic; 
    using Domain; 

    public interface IDatabaseService 
    { 
     void InsertEvent(Event @event); 
     void UpdateEvent(Event @event); 
     void DeleteEvent(long recordId); 
     IEnumerable<Event> SelectEventsForList(); 
    } 
} 

startup.cs形式服務

public class Startup 
{ 
    public Startup(IHostingEnvironment env) 
    { 
     var builder = new ConfigurationBuilder() 
      .SetBasePath(env.ContentRootPath) 
      .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) 
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 
      .AddEnvironmentVariables(); 

     this.Configuration = builder.Build(); 


    } 

    public IConfigurationRoot Configuration { get; } 

    // This method gets called by the runtime. Use this method to add services to the container. 
    public void ConfigureServices(IServiceCollection services) 
    { 

     // Add framework services. 
     services.AddScoped(provider => 
     { 
      var connectionString = new SqlConnection(Configuration["ConnectionStrings:DevConnection"]); 
      return connectionString; 
     }); 
     // Register the Swagger generator, defining one or more Swagger documents 
     services.AddSwaggerGen(c => 
     { 
      c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" }); 
     }); 
     services.AddMvc(); 

     services.AddTransient<IGetEventsListQuery, GetEventsListQuery>(); 


    } 

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     loggerFactory.AddConsole(this.Configuration.GetSection("Logging")); 
     loggerFactory.AddDebug(); 


     app.UseMvc(); 

     // Enable middleware to serve generated Swagger as a JSON endpoint. 
     app.UseSwagger(); 

     // Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint. 
     app.UseSwaggerUI(c => 
     { 
      c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); 
     }); 
    } 
} 

}

這是IDatabaseService的持久性執行

namespace Demeter.Persistance.Services 
{ 
    using System; 
    using System.Collections.Generic; 
    using Application.Interfaces; 
    using Domain; 
    using System.Data; 
    using System.Data.SqlClient; 
    using Dapper; 

    public class DatabaseService : IDatabaseService 
    { 
     public void InsertEvent(Event @event) 
     { 
      throw new NotImplementedException(); 
     } 

     public void UpdateEvent(Event @event) 
     { 
      throw new NotImplementedException(); 
     } 

     public void DeleteEvent(long recordId) 
     { 
      throw new NotImplementedException(); 
     } 

     public IEnumerable<Event> SelectEventsForList() 
     { 
      using (IDbConnection dbConnection = Connection) 
      {  
       return dbConnection.Query<Event>("SELECT * FROM Event"); 
      } 

     } 

     public IDbConnection Connection 
     { 
      get 
      { 
       return new SqlConnection(connectionString); 
      } 
     } 

     public DatabaseService(string connectionString) 
     { 
      this.connectionString = connectionString; 
     } 

     private readonly string connectionString; 

    } 
} 
+1

你有沒有在你的啓動註冊'IDatabaseService'? – DavidG

+0

你的DI初始化代碼在哪裏?正如@DavidG所說,你是否註冊過'IDatabaseService'的具體類型? –

+0

我不這麼認爲。這是我第一次使用asp.net CORE以域爲中心的架構。我可以問你如何在啓動時註冊IDatabaseService? – NinjaDeveloper

回答

2

您需要註冊IDatabaseService到ASP.NET核心的依賴注入引擎。

這是您的Startup.cs文件的ConfigureServices方法內部完成。

通過查看您的DatabaseService實施,它似乎取決於連接字符串,但在ConfigureServices方法中,您已提供完整的SqlConnection

要使用DI使一切工作,你需要做出一些改變,直接在構造函數中使用連接:

public void ConfigureServices(IServiceCollection services) 
{ 
    // Add framework services. 
    services.AddScoped<IDbConnection>(provider => new SqlConnection(Configuration["ConnectionStrings:DevConnection"])); 
    // Register the Swagger generator, defining one or more Swagger documents 
    services.AddSwaggerGen(c => 
    { 
     c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" }); 
    }); 
    services.AddMvc(); 

    services.AddTransient<IGetEventsListQuery, GetEventsListQuery>(); 

    // Register your database service 
    services.AddScoped<IDatabaseService, DatabaseService>(); 
} 

public class DatabaseService : IDatabaseService 
{ 
    public void InsertEvent(Event @event) 
    { 
     throw new NotImplementedException(); 
    } 

    public void UpdateEvent(Event @event) 
    { 
     throw new NotImplementedException(); 
    } 

    public void DeleteEvent(long recordId) 
    { 
     throw new NotImplementedException(); 
    } 

    public IEnumerable<Event> SelectEventsForList() 
    { 
     _dbConnection.Query<Event>("SELECT * FROM Event"); 
    } 

    public DatabaseService(IDbConnection dbConnection) 
    { 
     _dbConnection = dbConnection; 
    } 

    private readonly IDbConnection _dbConnection; 

} 

在這個例子中,我添加了註冊爲「作用域」,因爲它似乎有一個直接依賴於數據庫連接(也聲明爲範圍)。

這也將確保單個IDatabaseService創建和每個請求使用。

2

您還沒有註冊的具體類型你的IDatabaseService inter面對。添加一行:

services.AddTransient<IDatabaseService, DatabaseService>(); 

不這樣做,將DI框架並不知道如何注入的構造函數GetEventsListQuery類。

我推薦的依賴注入是如何在對.NET核心讀完the docs