私は、REST APIの実行時にデータベースへの接続を変更したいです。私はリクエストの変数を入れて、Apiがどの接続文字列を使うかを決めさせたい。MVC WEBAPI 2で実行時にデータベースを変更する
例: 私は変数 "dbid"を "開発"という値でリクエストヘッダに入れ、それをApiに送信します。
APIはヘッダを見て、web.configファイルから正しいれたconnectionStringを取得します。
私は三つの層(データ、ビジネス、API)を持っています。データには、データを取得および設定するためのEntityFrameworkが含まれています。このように:ビジネスで
public class WebsiteContext : IocDbContext, IWebsites
{
public DbSet<Website> Websites { get; set; }
public IEnumerable<Website> GetAll()
{
return Websites.ToList();
}
}
(IoCDbContext.cs)
public class IocDbContext : DbContext, IDbContext
{
public IocDbContext() : base("develop")
{
}
public void ChangeDatabase(string connectionString)
{
Database.Connection.ConnectionString= connectionString;
}
}
私はdatalayerからデータを取得し、ためにいくつかの論理ここで必要とされないもの(が、それでも良いを行うためのクラスを持っていますストーリー)。
public class Websites : IWebsites
{
private readonly Data.Interfaces.IWebsites _websiteContext;
#region Constructor
public Websites(Data.Interfaces.IWebsites websiteContext)
{
_websiteContext = websiteContext;
}
#endregion
#region IWebsites implementation
public IEnumerable<Website> GetWebsites()
{
List<Data.Objects.Website> websiteDtos = _websiteContext.GetAll().ToList();
return websiteDtos.Select(web => web.ToModel()).ToList();
}
#endregion
}
public static class WebsiteMapper
{
public static Website ToModel(this Data.Objects.Website value)
{
if (value == null)
return null;
return new Website
{
Id = value.Id,
Name = value.Name
};
}
}
そして、少なくとも最後のではなく、コントローラ:
public class WebsiteController : ApiController
{
private readonly IWebsites _websites;
public WebsiteController(IWebsites websites)
{
_websites = websites;
}
public IEnumerable<Website> GetAll()
{
return _websites.GetWebsites().ToList();
}
}
マイUnityコンフィギュレーション:
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<Business.Interfaces.IWebsites, Websites>();
container.RegisterType<IDbContext, IocDbContext>();
container.RegisterType<IWebsites, WebsiteContext>();
// e.g. container.RegisterType<ITestService, TestService>();
GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
あなたが名前の接続文字列を見ることができるように "発展" でありますデフォルトで使用されます。これにより、「ウェブサイト」という名前のウェブサイトが返されます。今私はヘッダ変数 "dbid"を "live"に変更します。 APIはこれを見て、 "live"という名前に対応する接続文字列を取得する必要があります。この最後の部分は私が試しているものですが、何も動作しません。
この私が試した:
- をWEBAPIにセッションを追加します。これは私がREST APIをステートレスなアイデアを破る意味:
- 行われていない静力学はどちらか動作しないことができ、誰もが同じたconnectionStringを取得する可能性があるため、そのユーザは、特定の
- グーグルが、例のほとんどは私のために動作しません StackOverflowのの検索
- ...前のポイントを参照してください。
これは狂気私を運転しています!リクエストヘッダーの値によって与えられる接続文字列を変更する方法が必要です。
だから、私はまっすぐに、これを取得してみましょう:ISiteContexではどの接続文字列を使用するかを決定ロジックのですか? (siteContext.SiteTypeに記述されているように)。もしそうなら、あなたは私を助けて、そのインターフェースの実装を追加できますか? –
実装コードをいくつか追加しました。それが役に立ったら教えてください。ルートの代わりにヘッダーを使用するように簡単に変更することも、web.configに接続文字列の値を追加して、web.configからコピーした書式設定された接続文字列の代わりに「名前」を使用して参照することもできます。 –
うん、それは動作します。それを見ると、それはとても簡単で簡単に見えるようになります。私は完全にHttpContext.Current.Request.RequestContext.RouteData(リクエストのヘッダー)を見逃してしまったので、リクエストから情報を取得して正しい変数に入れる方法を理解できませんでした。そしてコンストラクタでそうすることによって。まあ、別のことが学んだ。あなたの完璧な説明と助けをありがとう –