大规模 ORM 的依赖注入:动态问题

发布于 2024-11-17 00:40:18 字数 2073 浏览 3 评论 0 原文

我已经开始从事一个 MVC 3 项目,该项目需要来自庞大的现有数据库的数据。

我的第一个想法是继续使用 EF 4.1 并创建一堆 POCO 来表示我需要的表,但我开始认为映射会变得过于复杂,因为我只需要某些表中的某些列表格。(感谢 Steven 在评论中进行澄清。

所以我想我应该给大规模 ORM 尝试一下,我通常使用工作单元实现,这样我就可以使所有内容很好地解耦。使用依赖注入。这是我对 Massive 的一部分:

public interface ISession
{
    DynamicModel CreateTable<T>() where T : DynamicModel, new();

    dynamic Single<T>(string where, params object[] args) 
        where T : DynamicModel, new();

    dynamic Single<T>(object key, string columns = "*") 
        where T : DynamicModel, new();

    // Some more methods supported by Massive here
}

这是我对上述接口的实现:

public class MassiveSession : ISession
{
    public DynamicModel CreateTable<T>() where T : DynamicModel, new()
    {
        return new T();
    }

    public dynamic Single<T>(string where, params object[] args) 
        where T: DynamicModel, new()
    {
        var table = CreateTable<T>();
        return table.Single(where, args);
    }

    public dynamic Single<T>(object key, string columns = "*") 
        where T: DynamicModel, new()
    {
        var table = CreateTable<T>();
        return table.Single(key, columns);
    }
}

问题出在 First()Last()FindBy() 方法基于名为 DynamicModel动态 对象,并且定义任何上面的方法;它通过从 TryInvokeMethod() 实现来处理它们rel="nofollow noreferrer">DynamicObject 相反:

public override bool TryInvokeMember(InvokeMemberBinder binder, 
    object[] args, out object result) { }

我不知道如何在我的 ISession 中“连接”这些方法。我的 ISession 如何提供对 First()Last()FindBy() 的支持?

换句话说,我如何使用 Massive 的所有功能,同时仍然能够将我的类与数据访问分离?

I've started working on an MVC 3 project that needs data from an enormous existing database.

My first idea was to go ahead and use EF 4.1 and create a bunch of POCO's to represent the tables I need, but I'm starting to think the mapping will get overly complicated as I only need some of the columns in some of the tables. (thanks to Steven for the clarification in the comments.

So I thought I'd give Massive ORM a try. I normally use a Unit of Work implementation so I can keep everything nicely decoupled and can use Dependency Injection. This is part of what I have for Massive:

public interface ISession
{
    DynamicModel CreateTable<T>() where T : DynamicModel, new();

    dynamic Single<T>(string where, params object[] args) 
        where T : DynamicModel, new();

    dynamic Single<T>(object key, string columns = "*") 
        where T : DynamicModel, new();

    // Some more methods supported by Massive here
}

And here's my implementation of the above interface:

public class MassiveSession : ISession
{
    public DynamicModel CreateTable<T>() where T : DynamicModel, new()
    {
        return new T();
    }

    public dynamic Single<T>(string where, params object[] args) 
        where T: DynamicModel, new()
    {
        var table = CreateTable<T>();
        return table.Single(where, args);
    }

    public dynamic Single<T>(object key, string columns = "*") 
        where T: DynamicModel, new()
    {
        var table = CreateTable<T>();
        return table.Single(key, columns);
    }
}

The problem comes with the First(), Last() and FindBy() methods. Massive is based around a dynamic object called DynamicModel and doesn't define any of the above method; it handles them through a TryInvokeMethod() implementation overriden from DynamicObject instead:

public override bool TryInvokeMember(InvokeMemberBinder binder, 
    object[] args, out object result) { }

I'm at a loss on how to "interface" those methods in my ISession. How could my ISession provide support for First(), Last() and FindBy()?

Put it another way, how can I use all of Massive's capabilities and still be able to decouple my classes from data access?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

○闲身 2024-11-24 00:40:18

我知道这个问题已经得到解答 - 但是 Massive 中的每个方法都被标记为虚拟的,因此您可以轻松地模拟它。我可能会建议这样做。或者 - 别打扰。

我目前正在我的项目中为 MVC3 视频执行此操作,并从 Rails 的剧本中获取页面 - 将我的查询作为对象上的静态方法提供,然后从那里开始。我让我的测试命中数据库 - 它根本不会减慢速度,并且可以轻松摆脱所有机器。

Rails 中没有 DI/IoC,这是一种幸福的感觉。

I know this question has been answered - but every method in Massive is marked as virtual so you can Mock it easily. I might suggest that. OR - don't bother.

I'm doing this on my project currently for the MVC3 videos and taking a page from the Rails' playbook - offer my queries as static methods on my objects and go from there. I let my tests hit the database - it doesn't slow things down at all and is quite freeing to get rid of all the machinery.

There's no DI/IoC in Rails, and it's a happy feeling.

荒路情人 2024-11-24 00:40:18

界面

基本上,对于 ISession 的 Find、Last 和 FindBy 签名,您有几个界面明智的选项。

如果您想与动态参数名称保持相同的语法,First、Last 和 Find 都应该是 getter,并使用实现 bool TryInvoke(InvokeBinder binder, object[] args, out object result)的 DynamicObject 返回动态code> 将为您提供相同的动态 Find(column:val, otherColum:otherVal) 语法。这是一个粗略的基本示例:

    public class MassiveSession : ISession
{ 

    ...

    public dynamic Find{
           get {
               return new DynamicInvoker(this,name:"Find");
           }
    }

    public class DynamicInvoker : DynamicObject{
        ...
        public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
        {
             ...
             return true;          
        }

    }
}

如果您想要完全静态定义的方法,您只需执行 IDictionary 的单个参数或其他操作即可为您提供密钥对。

将调用转发到 Massive 动态方法

也有两种方法可以实现此目的。

最简单的方法是使用开源框架 ImpromptuInterface,它允许您以编程方式调用动态方法就像 c# 编译器 (包括动态命名参数)。

var arg = InvokeArg.Create;
return Impromptu.InvokeMember(table, "Find", arg("column", val),arg("otherColum", otherVal));

或者您可以尝试伪造进入 TryInvokeMember 的参数;

The Interface

Basically you have a couple of options interface wise for the signature for your ISession's Find, Last and FindBy.

If you want to keep the same syntax with the dynamic argument names First, Last and Find should all be getters and return dynamic with a DynamicObject that Implements bool TryInvoke(InvokeBinder binder, object[] args, out object result) that will give you the same dynamic Find(column:val, otherColum:otherVal) syntax. Here is a rough basic example:

    public class MassiveSession : ISession
{ 

    ...

    public dynamic Find{
           get {
               return new DynamicInvoker(this,name:"Find");
           }
    }

    public class DynamicInvoker : DynamicObject{
        ...
        public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
        {
             ...
             return true;          
        }

    }
}

If you want completely statically defined methods you are just going to have to do a single parameter of IDictionary or something to give you the key pairs.

Forwarding the call to the Massive dynamic method

There are two ways to do this as well.

The easy way is to use the open source framework ImpromptuInterface that allows you to programmatically call dynamic methods just like the c# compiler (including dynamic named parameters).

var arg = InvokeArg.Create;
return Impromptu.InvokeMember(table, "Find", arg("column", val),arg("otherColum", otherVal));

Or you can just try to fake the parameters coming into the TryInvokeMember;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文