Подтвердить что ты не робот

Dependecy Injection с массивным ORM: динамические проблемы

Я начал работать над проектом MVC 3, которому нужны данные из огромной существующей базы данных.

Моя первая идея заключалась в том, чтобы продолжить использование EF 4.1 и создать группу POCO для представления таблиц, которые мне нужны, но я начинаю думать, что сопоставление будет чрезмерно сложным, поскольку мне нужно только некоторые из столбцы в некоторых таблицах. (спасибо Steven для пояснения комментариев.

Так что я думал, что дам Massive ORM попробовать. Обычно я использую реализацию Unit of Work, поэтому я могу сохранить все красиво развязанными и использовать Injection Dependency. Это часть того, что у меня есть для 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(). Massive основан на объекте dynamic с именем DynamicModel и не определяет какой-либо из вышеперечисленных методов; он обрабатывает их через реализацию TryInvokeMethod(), превышающую DynamicObject:

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

Я не могу понять, как "взаимодействовать" с этими методами в моем ISession. Как моя ISession обеспечит поддержку First(), Last() и FindBy()?

По-другому, как я могу использовать все возможности Massive и все еще иметь возможность отделить мои классы от доступа к данным?

4b9b3361

Ответ 1

Интерфейс

В принципе, у вас есть несколько вариантов интерфейса, подходящих для подписи для вашего ISession Find, Last и FindBy.

Если вы хотите сохранить один и тот же синтаксис с именами динамических аргументов First, Last и Find, все должны быть getters и возвращать динамические с помощью DynamicObject, который реализует bool TryInvoke(InvokeBinder binder, object[] args, out object result), который даст вам тот же синтаксис dynamic 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, который позволяет программным способом вызывать динамические методы, подобно компилятору С# (включая динамические именованные параметры).

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

Или вы можете просто попытаться подделать параметры, входящие в TryInvokeMember;

Ответ 2

Я знаю, что на этот вопрос был дан ответ - но каждый метод в Massive отмечен как виртуальный, чтобы вы могли легко его пробить. Я мог бы предположить это. ИЛИ - не беспокойтесь.

Я делаю это в своем проекте в настоящее время для видео MVC3 и беру страницу из рецензии Rails - предлагаю свои запросы как статические методы на своих объектах и ​​оттуда. Я позволил своим испытаниям попасть в базу данных - это совсем не замедляет работу и освобождает все механизмы.

Там нет DI/IoC в Rails, и это счастливое чувство.