使用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]);

正如你所看到的,是最后一个绑定难倒了我?如何将构造函数对象参数绑定到现有单例绑定对象上的方法调用?

就像我在开始说的,我在这方面非常绿色,也许我正在做的一切都错了,但我已经搜索了网络,找不到任何关于这些技术一起使用的信息,所以任何帮助将非常感谢

使用Ninject绑定Vita ORM

因此,对于所有在网上徘徊的孤独的灵魂来说,这是我最终得出的结论:

        /*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();
    }

就是这样。现在我得到一个新的连接上下文每个请求,我是一个快乐的露营者