2016-11-16 79 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(); 
    } 

而那就是它。现在我为每个请求获得一个新的连接上下文,我是一个快乐的露营者