我对Ninject和Vita ORM (vita docs)都是新手,只是想出一个依赖注入的绑定策略,真的很感谢大家的帮助。
首先,我的应用程序被分成3层,即数据层(使用Vita ORM,因此本质上它是一个类似于EF的dbContext的单个EntityApp类),然后我有一个定义良好的接口的服务层(以及使用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();我假设将调用构造器,并且在那里我已经正确地初始化了上下文(这也应该只被调用一次)
然后在服务对象中,我想要这样做
以下是服务实现
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]);正如你所看到的,是最后一个绑定难住了我?如何将构造器对象参数绑定到现有单例绑定对象上的方法调用?
就像我在一开始说的那样,我对此很生疏,也许我做错了,但我已经搜索了网络,找不到任何关于这些技术一起使用的信息,所以任何帮助都将不胜感激。
发布于 2016-12-07 19:47:39
因此,对于所有在网络上遇到类似问题的孤独的灵魂来说,这是我最终要面对的:
/*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();
}就是这样。现在,我为每个请求获得一个新的连接上下文,我是一个快乐的露营者
https://stackoverflow.com/questions/40628309
复制相似问题