2013-10-02 5 views
4

Мне поручено модульное приложение C#, которое является переписанием очень большого приложения Delphi (у DB есть 249 таблиц!). Бизнес-ограничения запрещают полную редизайн для .NET и лучшую общую архитектуру, поэтому мы в основном просто инкрементно переписываем модуль для модуля приложения Delphi на C#. До завершения пакет будет содержать смесь ожидающих перезаписывания и модулей приложений C#, которые я хочу интегрировать с помощью MEF.Вопросы по стратегии и структуре MEF

Приложение относится к Time-and-Attendance and Access-Control и имеет различные бизнес-направления, такие как «Выход сотрудников» и «Посетители». Я думаю, что это должны быть отдельные проекты, где мы можем поменять перезаписанный проект C#, и он будет импортирован в контейнер MEF. Каждый проект будет экспортировать IBusinessArea, как определение самого высокого уровня, тогда они будут экспортировать стандартные, общие интерфейсы, такие как IService, которые предоставляют услуги, доступные в бизнес-области, например CreateEmployee. Каждая услуга будет классом, чтобы стандартизировать интерфейс службы с контейнером и содержать метаданные службы, такие как Command для этой услуги, данные о том, кто может использовать эту услугу, и т. Д.

Am I заголовок в правильном направлении, и если да, то как мне хранить и выставлять IBusinessArea и IService метаданные как классы, а также легионы нетипизированных атрибутов метаданных?

+0

Помог ли мой ответ? – Marc

ответ

4

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

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

Даже если вы используете типизированные функции экспорта и использования метаданных, метаданные на самом деле не являются типичными. Скажем, у вас есть интерфейс «IMetadata» с свойством «PropertyA», и вы регистрируете тип (позволяет называть его Foo ради творчества), который украшен соответствующим атрибутом в a, что MEF вызывает typesafe, способ (метаданные, реализующие IMetadata). Теперь предположим, что у вас есть второй интерфейс метаданных «IMetadataB», который также имеет свойство, называемое PropertyA. Если вы теперь запросите разрешение Foo с метаданными IMetadataB, вы получите экземпляр, который вы зарегистрировали в первую очередь, потому что MEF удовлетворяет PropertyA, существующим в парах ключ-значение метаданных, и строит тип метаданных соответствующего прокси, который реализует IMetadataB.

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

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

В принципе, я определяю интерфейс и базовое слово для своих метаданных, скажем MetadataBase со строковым свойством, называемым Description.

public class MetadataBase : IMetadata 
{ 
    public string Description { get; set; } 
} 

Затем для каждого класса я хочу иметь метаданные, я вывести класс (FooMetadata) из этого базового класса и определить его частично в XAML. Тогда, в XAML, я определить конкретный класс значение свойства, например:

<md:MetadataBase.Description> 
    The description of my class goes here 
</md:MetadataBase.Description> 

С пользовательского атрибута, я связать тип метаданных для моего фактического класса:

[Export(typeof(IFoo))] 
[AssociatedMetadata(typeof(FooMetadata))] 
public class Foo : IFoo 
{ 
    // Whatever 
} 

метод расширения для объектов позволяет считывать метаданные с помощью отражения:

public static IMetadata GetMetadata(this object objectWithMetadata) 
{ 
    // Read attribute type 
    // Create instance of the metadata type, i.e. FooMetadata 
    // A caching mechanism can be implemented, if needed, but, honestly, 
    // my really big metadata objects including images and stuff like this 
    // are created within 3-5 ms 
    // Return this instance 
} 

Теперь вы в основном там, вы можете прочитать метаданные любого объекта, который имеет метаданные, как это:

var myObjectsMetadata = myObject.GetMetadata(); 

Вы можете использовать эти метаданные в MEF, когда вы делаете ваш AssociatedMetadataAttribute реализовать интерфейс и зарегистрировать свои типы с помощью метаданных этого интерфейса. Ничто не будет замешано, потому что у вас есть один тип метаданных для всего, что содержит одно свойство, и ничего больше (тип).

Это решение не подходит для всего, но мне оно нравится, и ваш вопрос - хороший повод представить его. Надеюсь, поможет!

+0

Для меня самой мощной особенностью метаданных экспорта MEF является то, что вы можете получить к ним доступ, не создавая экспортированную часть. Для сценариев надстройки это очень полезно. Точки, которые вы делаете в отношении безопасности типов, действительны и должны быть четко указаны в документации MEF, чтобы новички имели более легкое время. При этом один или два класса метаданных должны быть достаточными для большинства приложений. Если я не ошибаюсь, ваш подход использует один, IMetadata. Я не имею опыта в WPF, хотя и не могу сказать, может ли ваш подход заменить на метаданные экспорта MEF. –

+0

@PanosRontogiannis, Правильно, я использую один интерфейс метаданных. Вы все равно можете экспортировать метаданные через MEF и получить доступ к нему без фактического разрешения экспортируемой части. Для меня это лучшее из обоих миров. – Marc

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