在MEF战略和结构问题 [英] Questions on MEF strategy and structure

查看:193
本文介绍了在MEF战略和结构问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我负责模块化一个C#应用程序,是一个非常大的Delphi应用程序重写(数据库拥有249桌!)。业务限制禁止一个完全重新设计的.NET和更好的总体架构,因此我们是在C#中的Delphi应用程序的模块基本上只是逐步重写模块。直到完成,该套件将包括待决的重写的混合物,和C#程序模块我想用MEF集成

I am tasked with modularizing a C# app that is a rewrite of a very large Delphi app (the DB has 249 tables!). Business constraints proscribe a complete redesign for .NET and better overall architecture, so we are basically just incrementally rewriting module for module of the Delphi app in C#. Until finished, the suite will comprise a mixture of pending rewrites, and C# app modules I want to integrate using MEF.

该应用程序本身涉及时间与考勤和访问控制,并拥有像员工休假和游客不同的业务领域。我想这些应该是单独的项目,在这里我们可以换出一个重写的C#项目,它将被导入到MEF容器。每个项目都将导出 IBusinessArea ,作为最高级别的定义,那么这将出口标准,共享的接口,如 IService ,即引进一个商务区提供的服务,如 CreateEmployee 。每个服务将是一个类,为了规范与容器服务的接口,包含服务元数据,如命令的服务,对谁的数据可能使用该服务,等等。

The app concerns itself with Time-and-Attendance and Access-Control, and has diverse business areas like 'Employee Leave' and 'Visitors'. I think these should be separate projects, where we can swap out a rewritten C# project, and it will be imported into the MEF container. Each project will export an IBusinessArea, as a highest level definition, then these will export standard, shared interfaces like IService, that introduce the services available in a business area, like CreateEmployee. Each service will be a class, in order to standardise the interface of the service with the container, and contain service metadata, such as a Command for the service, data on who may use the service, etc.

我是朝着正确的方向前进,如果是这样,我怎么存储和揭露 IBusinessArea IService 元数据类,与非类型化的元数据军团属性?

Am I heading in the right direction, and if so, how do I store and expose IBusinessArea and IService metadata as classes, versus legions of untyped metadata attributes?

推荐答案

到目前为止,你说的一切听起来合理的给我。您模块化某些领域,确定不同层次的抽象接口,并具有不同接口的输出你的每一个模块,即每个模块将被登记为它实现多个接口。您将能够根据抽象您所需要的水平,以解决您的模块,获得所有服务,所有业务领域,等等。所以,在我看来,你是朝着正确的方向发展。

So far, everything you say sounds reasonable to me. You modularize certain areas, define interfaces on different levels of abstraction and export each of your modules with different interfaces, i.e. each module will be registered as several interfaces it implements. You'll be able to resolve your modules according to the level of abstraction you require, get all services, all business areas, etc. So, in my opinion you are heading in the right direction.

如何处理元数据? MEF提供元数据导出,这似乎是一个合理的事情来使用。也许我没有得到它完全是,但我已经非常糟糕的经历与MEF元数据导出。据我记忆所及,MEF将元数据存储为键值对,其中键是一个字符串。

How to deal with metadata? MEF provides exporting of metadata, which would appear to be a reasonable thing to use. Maybe I didn't get it entirely, but I have made really bad experiences with MEF metadata export. As far as I can recall, MEF stores metadata as key-value pairs, where the key is a string.

即使您使用类型化的元数据导出和使用功能,元数据是不是真的类型安全。假设你有一个接口IMetadata'有一个名为PropertyA的财产和您注册类型(可以称之为创意的缘故)装饰有根据的属性中的一个,有什么MEF调用的类型安全的,地(元数据实现IMetadata)。现在,假设你有一个第二元数据接口IMetadataB其中也有一个名为 PropertyA 属性。如果你现在要求解决与元数据的 IMetadataB 你会得到你在第一时间注册的实例,因为MEF是满意 PropertyA 是存在的元数据中的键值对,并建立一个根据代理的元数据类型,它实现 IMetadataB

Even if you use the typed metadata export and usage functions, the metadata is not really typesafe. Say you have an interface 'IMetadata' with a property called 'PropertyA' and you register a type (lets call it Foo for the sake of creativity) which is decorated with an according attribute in a, what MEF calls typesafe, manner (metadata implementing IMetadata). Now suppose you have a second metadata interface 'IMetadataB' which also has a property called PropertyA. If you now request resolving Foo with metadata IMetadataB you'll get the instance you registered in the first place because MEF is satisfied with PropertyA being existent in the metadata key-value pairs and builds an according proxy metadata type which implements IMetadataB.

长话短说,也许我是不公平的MEF,但我停止使用MEF内置的元数据支持,并会建议你做同样的。

Long story short, maybe I'm being unfair to MEF, but I stopped using the MEF built in metadata support and would recommend you to do the same.

正如我在处理非常复杂而冗长的元数据,包括那种,我要紧紧地连接到我出口,我开发了一个系统,它的作品真的很好,我的班班单证的,虽然它是一个小位非常规:

As I'm dealing with very complex and lengthy metadata, including kind of documentations of classes which I want to be tightly coupled to the classes I export, I developed a system which works really well for me, although it is a little bit unconventional:

基本上,我定义一个接口和一个基类为我的元数据,比如元数据库与名为描述字符串属性

Basically, I define an interface and a baseclass for my metadata, say MetadataBase with a string property called Description.

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

之后,对每个班级我想有元数据,我从这项基类的类( FooMetadata ),并在XAML部分定义它。然后,在XAML中,我定义属性的类特定的值,例如:

Afterwards, for every class I want to have metadata for, I derive a class (FooMetadata) from this base class and define it partially in XAML. Then, in XAML, I define the class specific value of the property, for example:

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

通过自定义属性,我涉及的元数据类型,以我的实际的类:

With a custom attribute, I relate the metadata type to my actual class:

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

有关对象的扩展方法可以让你读了元数据通过反射:

An extension method for objects lets you read the metadata via reflection:

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
}

现在,你基本上是在那里,你可以看到它有元数据,像这样的任何对象的元数据:

Now, you're basically there, you can read the metadata of any object which has metadata like this:

var myObjectsMetadata = myObject.GetMetadata();

当你让你的 AssociatedMetadataAttribute 实现一个接口,并用这个接口的元数据注册的类型,您可以利用这些元数据在MEF。那什么事都混在一起,因为你有一种类型的元数据都持有一个属性,没有别的(类型)。

You can utilize this metadata in MEF when you make your AssociatedMetadataAttribute implement an interface and register your types with metadata of this interface. Nothing will get mixed up, because you have one type of metadata for everything which holds one property and nothing else (the type).

这个解决方案是不正确的方式去的一切,但我喜欢它,你的问题是一个很好的机会,以present它。希望它可以帮助!

This solution is not the right way to go for everything, but I love it and your question is a good occasion to present it. Hope it helps!

这篇关于在MEF战略和结构问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆