2016-01-26 21 views
14

Mam ASP.NET MVC Web Application 5 i Startup.cs widzę, że własność publicznaPrzechodząc ciąg połączenia aplikacji do repozytorium Class Library w ASP.NET 5 Korzystanie z IConfigurationRoot

IConfigurationRoot Configuration 

jest jest ustawiona na builder.Build();

całym aplikacji Web MVC mogę po prostu zrobić

Startup.Configuration["Data:DefaultConnection:ConnectionString"] 

uzyskać Conn ciąg f rom z pliku appsettings.json.

Jak mogę uzyskać ciąg połączenia określony w ASP.NET 5 MVC appsettings.json przekazany do mojej biblioteki klas Repozytorium za pomocą wstrzyknięcia konstruktora?

UPDATE:
Oto repozytorium podstawa, że ​​wszystkie inne repozytoria dziedziczyć (jak widać mam ustalony ciąg połączenia tu na razie):

public class BaseRepo 
{ 
    public static string ConnectionString = "Server=MYSERVER;Database=MYDATABASE;Trusted_Connection=True;"; 

    public static SqlConnection GetOpenConnection() 
    { 
     var cs = ConnectionString; 
     var connection = new SqlConnection(cs); 
     connection.Open(); 
     return connection; 
    } 
} 

W moim asp.net 5 aplikacji internetowych w moim pliku appsettings.json mam następujące, które jest równoznaczne z dodaniem ciąg połączenia w pliku web.config w .net 4.5 webapp:

"Data": { 
    "DefaultConnection": { 
     "ConnectionString": "Server=MYSERVER;Database=MYDATABASE;Trusted_Connection=True;" 
    } 
    } 

Dodatkowo wm y asp.net aplikacja 5 web Mam następujący kod domyślny w moim Startup.cs który ładuje konfigurację witryn do własności publicznej typu IConfigurationRoot:

public IConfigurationRoot Configuration { get; set; } 
// Class Constructor 
     public Startup(IHostingEnvironment env) 
     { 
      // Set up configuration sources. 
      var builder = new ConfigurationBuilder() 
       .AddJsonFile("appsettings.json") 
       .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); 

      if (env.IsDevelopment()) 
      { 
       // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709 
       builder.AddUserSecrets(); 
      } 

      builder.AddEnvironmentVariables(); 
      Configuration = builder.Build(); 
     } 

Teraz w mojej aplikacji sieci web ASP.NET, czy chciałbym aby uzyskać dostęp do którejkolwiek z appSettings mogę prosty wykonaj następujące czynności: Startup.Configuration["Data:DefaultConnection:ConnectionString"]

Ale niestety nie mogę tego zrobić z mojej klasy biblioteki ..

Jeśli ktoś chce spróbować i rysunek to tutaj są kroki odtworzyć:

  1. Utwórz nową aplikację sieci Web ASP.NET 5 MVC.
  2. Dodaj do projektu kolejny typ biblioteki klas (pakiet).
  3. wymyślić sposób przekazać AppSettings z ASP.NET MVC App 5 do Class Library

Po aktualizacji wciąż nie dość je zdobyć. Tu jest mój kodu:

public class BaseRepo 
{ 
    private readonly IConfigurationRoot config; 

    public BaseRepo(IConfigurationRoot config) 
    { 
     this.config = config; 
    } 
} 

Deklaracja ta klasa nie działa od BaseRepo wymaga param konstruktora teraz.

public class CustomerRepo : BaseRepository, ICustomerRepo 
{ 
    public Customer Find(int id) 
    { 
     using (var connection = GetOpenConnection()) 
     { 
      ... 
     } 
    } 
} 
+1

Nie powinieneś przepuszczać łańcucha połączenia, powinien on być określony w pliku web.config i powinieneś go pobrać w jednym miejscu w kodzie aplikacji. Gdziekolwiek ten pojedynczy punkt jest, powinien być traktowany jako zależność w obrębie klas, które tego wymagają. – Luke

+1

W ASP.NET 5 nie ma Web.Config i rzeczy są wykonane nieco inaczej. Wiem, jak ustawić ciąg połączenia w mojej aplikacji internetowej, ale wierzę w ASP.NET 5 mogę przekazać go do mojej biblioteki klas Repozytorium danych przy użyciu wtrysku konstruktora. –

+0

Właśnie nauczyłeś mnie czegoś nowego. Nie zdawałem sobie sprawy, że app.config zniknął, jestem najnowszą wersją. Czas, abym poszła i dowiedz się więcej ...: o) – Luke

Odpowiedz

18

na pliku Startup.cs Dodaj następującą metodę

public void ConfigureServices(IServiceCollection services) { 
    services.AddSingleton(_ => Configuration); 
} 

następnie zaktualizować swoją klasę BaseRepo jak ten

public class BaseRepo { 
    private readonly IConfiguration config; 

    public BaseRepo(IConfiguration config) { 
     this.config = config; 
    } 

    public SqlConnection GetOpenConnection() { 
     string cs = config["Data:DefaultConnection:ConnectionString"]; 
     SqlConnection connection = new SqlConnection(cs); 
     connection.Open(); 
     return connection; 
    } 
} 
+1

To jest dokładnie to, czego szukałem! Dzięki wielkie. –

+1

Jest jeden problem. Kiedy moje repozytorium potomne dziedziczy po BaseRepo, pojawia się komunikat o błędzie: BaseRepo nie zawiera konstruktora bez parametrów. Próbuję zrobić coś takiego jak klasa publiczna CustomerRepo: BaseRepo, ICustomerRepo –

+0

Dlaczego jej nie stworzysz? –

1

Jeśli ConfigureServices w projekcie na startUp.cs zawiera

services.AddEntityFramework() 
      .AddSqlServer() 
      .AddDbContext<YourDbContext>(options => 
       options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])); 

i repozytorium plik cs jest posiadanie konstruktora wtrysku, jak pokazano poniżej

public class MyRepo : IRepo 
{ 
    private readonly YourDbContext dbContext; 
    public MyRepo(YourDbContext ctx) 
    { 
     dbContext = ctx; 
    } 
} 

YourDbContext zostaną automatycznie rozwiązane.

+2

Niestety nie używam Entity Framework, więc nie mam konfiguracji DbContext. Używam Dapper w moim DAL, więc potrzebuję tylko ciąg połączenia aplikacji, aby utworzyć połączenie SQL. Czy jest jeszcze sposób na przeniesienie go z ustawień aplikacji do repozytorium? –

+0

Wygląda to na podstawie kodu, który robisz dobrze, czy możesz podać ogólny kod jak wygląda twoje repozytorium? –

+0

Zaktualizowałem swój wpis. Proszę zobaczyć. –

0

Co potrzebne jest, aby utworzyć klasę w projekcie biblioteki klasa aby uzyskać dostęp do appsettings.json w projekcie strony internetowej i zwraca ciąg połączenia.

{ 
    private static string _connectionString; 

    public static string GetConnectionString() 
    { 
     if (string.IsNullOrEmpty(_connectionString)) 
     { 
      var builder = new ConfigurationBuilder() 
      .AddJsonFile("appsettings.json"); 
      Configuration = builder.Build(); 
      _connectionString = Configuration.Get<string>("Data:MyDb:ConnectionString"); 
     } 
     return _connectionString; 
    } 
    public static IConfigurationRoot Configuration { get; set; } 

} 
8

Program ASP.NET zapewnia własny sposób przekazywania ustawień konfiguracyjnych.

Załóżmy, że masz to w swoim appSettings.json:

{ 
    "Config": { 
    "Setting1": 1, 
    "Setting2": "SO" 
    } 
} 

to trzeba klasę tak:

public class MyConfiguration 
{ 
    public int Setting1 { get; set; } 

    public string Setting2 { get; set; } 
} 

To pozwala skonfigurować usługę w tej konfiguracji poprzez dodanie następujący wiersz

services.Configure<MyConfigurationDto>(Configuration.GetSection("Config")); 

do ConfigureServices.

Następnie można wprowadzić konfigurację w konstruktorów, wykonując następujące czynności:

public class SomeController : Controller 
{ 
    private readonly IOptions<MyConfiguration> config; 

    public ServiceLocatorController(IOptions<MyConfiguration> config) 
    { 
     this.config = config; 
    } 

    [HttpGet] 
    public IActionResult Get() 
    { 
     return new HttpOkObjectResult(config.Value); 
    } 
} 

Ten przykład jest dla kontrolerów. Ale możesz zrobić to samo z innymi warstwami aplikacji.

1

Mam konstruktora w mojej klasie repozytorium, który przyjmuje ciąg połączenia db jako parametr. Działa to dla mnie, gdy dodaję moje repozytorium do iniekcji. W ConfigureServies() w pliku startup.cs dodać to:

services.AddScoped<IRepos>(c => new Repos(Configuration["DbConnections:ConnStr1"])); 

IRepos.cs jest interfejsem, Repos.cs jest klasa, która implementuje go. I oczywiście Konfiguracja to tylko odniesienie do zbudowanego obiektu IConfigurationRoot.

1

Istnieje już metoda rozszerzenia, za pomocą której można uzyskać ciągi połączeń specjalnie z pliku aspsettings.json.

  1. Zdefiniuj łańcuchy połączeń w Appsettings.json tak:

    { 
        "ConnectionStrings": { 
         "Local": "Data source=.\\SQLExpress;Initial Catalog=.......", 
         "Test:": "Data source=your-server;......" 
        }, 
        "Logging": { 
         "IncludeScopes": false, 
         "LogLevel": { 
          "Default": "Debug", 
          "System": "Information", 
          "Microsoft": "Information" 
         } 
        } 
    } 
    
  2. W swojej metodzie public void ConfigureServices(IServiceCollection services) wewnątrz Startup.cs, można uzyskać ciąg połączenia tak:

    var connectionString = this.Configuration.GetConnectionString("Local"); 
    
  3. Rozszerzenie GetConnectionString wynosi od Microsoft.Extensions.Configuration.
  4. Zapraszamy :)

UPDATE

nie chcę wchodzić w szczegóły na początku, bo tu kwestia została już oznaczona jako odpowiedź. Ale myślę, że mogę pokazać tutaj moje 2 centy.

Jeśli potrzebujesz całego obiektu IConfigurationRoot wstrzykniętego do Kontrolerów, @Chrono pokazało właściwą drogę.

Jeśli nie potrzebujesz całego obiektu, powinieneś po prostu uzyskać ciąg połączenia, przekazać go do DbContext wewnątrz połączenia ConfigureServices() i wprowadzić DbContext do kontrolerów. @ Prashant Lakhlani pokazał to poprawnie.

Po prostu mówię, że w @ Prashant Lakhlani post możesz zamiast tego użyć rozszerzenia GetConnectionString, aby trochę wyczyścić kod.

+0

Ograniczeniem tego jest potrzeba odniesienia do obiektu Configuration w klasie. Jest obecny w pliku Startup.cs, ale trzeba go wprowadzić do klasy. – ChrisP