2010-09-19 3 views
3

Так что у меня этот классВызывать статические инициализаторы типа посредством отражения возможно

public static class MyClass 
{ 
    static MyClass() 
    { 
     ... 
    } 
} 

который не имеет методов, полей и свойств. Все, что он делает, это обработчики подключений к статическим событиям, определенным в другом месте.

Поскольку инициализатор типа никогда не вызывается, поскольку статический класс никогда не обращается к действительности, события не подключаются.

Таким образом, я надеялся, что сможет вызвать инициализатор типа через отражение ala typeof(MyClass).TypeInitializer().Invoke(...), которое взрывается, с исключением того, что MyClass является абстрактным классом.

В конечном итоге приложение будет иметь другие статические классы с тем же форматом, который соответствует бизнес-правилам. Прежде чем что-либо будет сохранено в БД, будут запущены статические события, соответствующие типу сохраняемого объекта. Поэтому, если то, что я хочу сделать, оказывается невозможным, любые рекомендации по рефакторингу должны будут следовать этой структуре.

EDIT:

я, возможно, не было совершенно ясно, что именно я пытаюсь сделать. В основном у меня есть уровень данных, где вы можете инициализировать экземпляр DataContext, а затем, когда вызывается SubmitChanges(), я проверяю ChangeSet для вставки/обновления/удаления и запускает статические события для каждого типа, который встает/обновляется/удаляется. Все это отлично работает, я просто ищу способ подключения обработчиков к событиям один раз, когда приложение запускается. Так что я играл с этим было:

static DataContext() 
{ 
    System.Reflection.Assembly.GetExecutingAssembly().GetTypes() 
     .Where(t => t.Namespace == 'Data.Business') 
     .ToList() 
     .ForEach(t => { 
      // invoke the static TypeInitializer here, 
      // so that it can wire up it's event handlers. 
     }); 
} 

Я мог бы использовать статический метод Initialize, но так как они только должны всегда быть инициализированы один раз, я думал TypeInitializer.

EDIT 2:

Я прочитал на MEF и это действительно дает возможность делать то, что я хотел сделать.

+2

Вам когда-нибудь приходило в голову, что это просто плохой/неработоспособный дизайн? – x0n

+0

Что плохой дизайн? Бизнес-уровень? Должен ли я помещать бизнес-правила в уровень представления? или вы имели в виду статическую природу? Я просто думал, что было бы более эффективно регистрировать один набор событий для всего слоя данных, чем новый набор событий для каждого контекста данных. –

ответ

5

Почему бы просто не сделать статический метод, то есть инициализировать(), который связывает все обработчики событий и просто вызывает MyClass.Initialize()?

+1

Или даже метод HelloWorld(). Все будет бить Отражение. –

+0

Почему люди так против отражения? это будет выполняться внутри инициализатора типа, поэтому удар производительности пренебрежимо мал. –

+0

Я не против размышлений, но это последний выбор для большинства вещей. Наличие отдельного метода инициализации просто проще. Что вы получаете, используя отражение в этом случае, когда можете полностью избежать этого? Существуют и другие способы обеспечения того, чтобы обработчики событий подключались только один раз. –

5

Вы можете использовать метод RuntimeHelpers.RunClassConstructor запустить статический конструктор:

RuntimeHelpers.RunClassConstructor(typeof(MyClass).TypeHandle); 

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

0

сделать следующую поправку в коде:

RuntimeHelpers.RunClassConstructor(typeof(MyClass).TypeHandle); 

Надеется, что это помогает!

Смежные вопросы