使用Ninject绑定Vita ORM

时间:2016-11-16 09:26:42

标签: c# orm ninject

我是Ninject和Vita ORM(vita docs)的新手,我只是遇到了依赖注入绑定策略的问题,非常感谢任何帮助。

首先,我的应用程序分为3层,即数据层(使用Vita ORM,因此本质上它是一个类似于dbContext for EF的单个EntityApp类),然后我有一个具有良好定义的接口的服务层(和现有的)使用我的当前存储库模式使用dapper.net实现的实现,最后是一个简单的MVC Web应用程序,控制器调用服务层。

目前我正在使用ninject构造函数交互将repo注入服务并将服务注入控制器并相应地进行范围设定。这很有效,因为一切都是接口驱动的,服务/存储库之间没有共享的上下文。

但现在引入了一个"实体上下文"我需要在app中创建一次上下文(如此单例范围),然后本质上就像每个请求打开一个新会话并将其传递给需要它的任何服务层对象。除此之外,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]);

正如你所看到的那样,最后一次绑定是在困扰我吗?如何将构造函数对象参数绑定到现有单例绑定对象上的方法调用?

就像我在开始时所说的那样,我在这方面非常绿色,也许我说这一切都错了,但我已经在网上搜索,无法找到有关这些技术的任何信息,因此任何帮助都将是非常感谢

1 个答案:

答案 0 :(得分: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();
    }

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