2016-11-16 90 views
0

我對Ninject和Vita ORM(vita docs)都是新手,我只是想解決依賴注入的綁定策略問題,非常感謝您的幫助。首先,我的應用程序分爲3層,即數據層(使用Vita ORM,因此本質上它是一個類似於EF的dbContext的單個EntityApp類),然後我有一個具有定義好的接口的服務層(以及現有的實現使用我的當前庫模式使用dapper.net),最後是一個簡單的MVC Web應用程序,控制器調用服務層。使用Ninject綁定Vita ORM

當前我正在使用ninject構造函數intection將服務和服務注入到控制器中,並相應地對其進行作用域。這很好,因爲一切都是由接口驅動的,服務/存儲庫之間沒有共享的上下文。

但是現在,隨着「實體上下文」的引入,我需要在應用程序中創建上下文一次(因此單例作用域),然後實質上就是爲每個請求打開一個新的會話並將其傳遞給任何服務層需要它的對象。除此之外,ORM需要在應用程序啓動時初始化(或者我認爲它可以懶惰地完成,但在應用程序啓動時會更好)

以下是由vita生成的一些代碼,用於如何初始化ORM

class Program { 

public static MyEntityApp App; 

static void Main(string[] args) { 
    Console.WriteLine(" Sample application for VITA-generated model. "); 
    Init(); 

    //Open session and run query 
    var session = App.OpenSession(); 
    var query = from ent in session.EntitySet<IConnections>() // just random entity 
       // where ?condition? 
       select ent; 
    var entities = query.Take(5).ToList(); 

    Console.WriteLine("Loaded " + entities.Count + " entities."); 
    foreach(var ent in entities) 
    Console.WriteLine(" Entity: " + ent.ToString()); // change to smth more meaningful 

    Console.WriteLine("Press any key ..."); 
    Console.ReadKey(); 
} 

private static void Init() { 

    App = new MyEntityApp(); 
    App.CacheSettings.AddCachedTypes(CacheType.FullSet /* , <fully cached entity types> */); 
    App.CacheSettings.AddCachedTypes(CacheType.Sparse /* , <sparsely cached entity types> */); 
    var connString = @"......."; 
    var driver = new Vita.Data.MsSql.MsSqlDbDriver(); 
    App.LogPath = "_appLog.log"; 
    var dbSettings = new DbSettings(driver, DbOptions.Default, connString, upgradeMode: DbUpgradeMode.Always); 
    App.ConnectTo(dbSettings); 
} 

} 

正如你所看到的,他們初始化並設置了一個靜態變量,它引用了上下文容器。從上面還可以看出,你需要調用var session = App.OpenSession();來處理上下文,所以我希望爲每個請求創建一個會話,然後將該會話注入到服務對象構造器中。

所以這是我迄今所做

/*Map the Vita ORM session into the request scope*/ 
kernel.Bind<MyEntities>().ToSelf().InSingletonScope(); 

我假設將調用構造器,裏邊有我已經正確初始化上下文(這也應該只被調用一次)

然後我想要做這樣的事情

這裏的服務對象是服務IMPL

private IEntitySession _Session { get; set; } 

public VitaSettingsServiceImpl(IEntitySession Session) 
{ 
    _Session = Session; 
} 

這裏是我在那個注入會話對象的嘗試......

kernel.Bind<ISettingsService>().To<VitaSettingsServiceImpl>().InRequestScope().WithConstructorArgument("Session", [WANT TO CALL MYENTITIES.OpenSession() HERE]); 

正如你可以看到它是最後的綁定被絆倒我嗎?我如何將構造器對象參數綁定到現有單例綁定對象上的方法調用?

就像我在開始時說的那樣,我非常青睞這個,也許我對這一切都錯了,但是我已經搜遍了網頁,並且找不到任何關於這些技術的信息被一起使用,所以任何幫助都會不勝感激

回答

0

所以對於所有的孤獨的靈魂曳類似問題的網站,這裏是我最終凸輪了:

 /*Map the Vita ORM session into the request scope*/ 
     kernel.Bind<SorbetEntities>().ToSelf().InSingletonScope(); 

     /*Map all the services to their respective implementations*/ 
     kernel.Bind<ISettingsService>().To<sorbet.Vita.VitaSettingsServiceImpl>().InRequestScope().WithConstructorArgument("Session", CreateVitaSession); 

,然後一個靜態擴展方法來執行,將返回的方法我連接上下文

private static object CreateVitaSession(IContext context) 
    { 
     return context.Kernel.Get<SorbetEntities>().OpenSession(); 
    } 

而那就是它。現在我爲每個請求獲得一個新的連接上下文,我是一個快樂的露營者