Кто-нибудь создал динамический класс .NET с открытым исходным кодом для предоставления частных функций / свойств другому классу? - PullRequest
2 голосов
/ 11 апреля 2011

И если это так, я бы очень хотел использовать его. У кого-нибудь есть указатели?

Моя цель состоит в том, чтобы устранить необходимость в проектах _accessor в моем тестовом решении. Я подумал, что если бы я создал динамический класс, то можно было бы записать, какие функции применяются к нему, а затем воспроизвести эти функции, используя отражение, на другом объекте. И с отражением мы можем вызвать частные функции. (Я хочу C # вариант C # #define private public.)

Я думаю, что смогу сделать это сам, но зачем это делать, если я могу повторно использовать какой-то код.

Ответы [ 4 ]

2 голосов
/ 11 апреля 2011

Если вы хотите использовать это для модульного тестирования, попробуйте изменить свой подход к модульному тестированию. Если вы переходите к каждому частному методу, ваши тесты очень тесно связаны с реальной реализацией.

Распространенными проблемами при использовании этого подхода являются

  • Очень хрупкие и трудные в обслуживании тесты
  • Ваши тесты с большой вероятностью отражают поведение и код вашего приложения
  • Существенное поведение ваших классов не очевидно из-за десятков тестов, описывающих каждую деталь

Каждый раз, когда вам необходимо выполнить рефакторинг некоторого кода, вам также придется менять несколько тестов. Это создаст огромный барьер для рефакторинга из-за времени и усилий, необходимых для исправления всех тестов на взлом. Вы даже рискуете создать нежелательное поведение, потому что вам нужно изменить столько тестов, чтобы изменить исходное поведение.

Я бы порекомендовал написать тесты, проверяющие поведение ваших классов. Если вы измените способ достижения этого поведения, вы вообще не будете ломать тесты и получите подтверждение, что ваш рефакторинг не изменил общее поведение.

Ваши тесты будут намного понятнее и будут определять действительно важные части вашего дизайна. Это помогает при рефакторинге или если кто-то (может быть, даже вы через несколько месяцев) должен снова войти в код.

1 голос
/ 11 апреля 2011

Я пытался создать класс сам, этот код работает для вызовов методов:

public class UnPrivatify : DynamicObject
{
    private object _obj;

    public UnPrivatify(object obj)
    {
        _obj = obj;
    }

    public override bool TryInvokeMember(
        InvokeMemberBinder binder,
        Object[] args,
        out Object result)
    {
        Type t = _obj.GetType();

        result = t.InvokeMember(binder.Name,
            System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public,
            null,
            _obj,
            args);

        return true;
    }
}
1 голос
/ 11 апреля 2011

Вы можете использовать расширения для динамического доступа к каждой частной функции.

public static class ObjectEx
    {
        public static object CallPrivateFunc(this object obj,string funcName, params object[] args)
        {
            const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod;
            return obj.GetType().InvokeMember(funcName, bindingFlags, null, obj, args);
        }
    }

Там использование:

public class MyClass
    {
        private void  MyFunc(int a,string c)
        {
            Trace.WriteLine("MyFunc called a:" + a + " c:" + c);
        }
    }
...
myClass.CallPrivateFunc("MyFunc", 10, "c");
...
0 голосов
/ 12 апреля 2011

Apache с лицензией Impromptu Interface имеет статические функции, которые используют DLR для вызова методов или свойств, независимо от того, является ли он закрытым или нет через binder.name.Должно быть довольно легко вызвать их внутри DynamicObject.

http://code.google.com/p/impromptu-interface/wiki/UsageReallyLateBinding

Редактировать :

В последней выпущенной версии 4.0является абстрактным классом ImpromptuForwarder , который при создании простого подкласса без изменений будет перенаправлять динамические вызовы частным методам / свойствам в целевом объекте.

...