使用Ninject绑定Vita ORM
本文关键字:ORM Vita 绑定 Ninject 使用 | 更新日期: 2023-09-27 18:18:04
我是Ninject和Vita ORM (Vita docs)的新手,只是遇到了依赖注入绑定策略的问题,非常感谢您的帮助。
首先,我的应用程序分成3层,即数据层(使用Vita ORM,因此本质上它是一个单一的EntityApp类,类似于EF的dbContext),然后我有一个具有良好定义接口的服务层(以及使用我当前使用dapper.net的存储库模式的现有实现),最后是一个简单的MVC web应用程序,控制器调用服务层。
目前,我正在使用对象构造函数感染来将repo注入到服务中,并将服务注入到控制器中,并相应地限定它们的作用域。这工作得很好,因为一切都是接口驱动的,服务/存储库之间没有共享上下文。
但是现在随着"实体上下文"的引入,我需要在应用程序中创建一次上下文(所以单例作用域),然后本质上想为每个请求打开一个新的会话,并将其传递给需要它的任何服务层对象。除此之外,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]);
正如你所看到的,是最后一个绑定难倒了我?如何将构造函数对象参数绑定到现有单例绑定对象上的方法调用?
就像我在开始说的,我在这方面非常绿色,也许我正在做的一切都错了,但我已经搜索了网络,找不到任何关于这些技术一起使用的信息,所以任何帮助将非常感谢
因此,对于所有在网上徘徊的孤独的灵魂来说,这是我最终得出的结论:
/*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();
}
就是这样。现在我得到一个新的连接上下文每个请求,我是一个快乐的露营者