XAF 组合关联<DC翻译博客十一>

DC: Combining associations(組合關聯)

Remember that the base idea of creating the Domain Component Technology is to  be able to compose  an application from reusable blocks – components. These blocks can be bought from third-party sources. This allows  you  to reuse well-polished blocks. But this also  means that you can not change the sources of these blocks. The other day, while working on XCRM, I tried to combine two component sets, but encountered a problem. In this post, I want to discuss this problem in detail.
记得,构建领域技术的基本理念是能用重用的块-组件来组成一个应用程序。这些块可以买自第三方。这允许你重用有用的块。但,这也意味着你不能更改这些资源块。有一天,当做XCRM,我试着组合两套组件,但遇到了一个问题。本篇,我想详细讨论这个问题。
Imagine that you have two domain component sets – Tasks and Ownership Security. Both of them contain DC interfaces, domain logic, Controllers, Actions, UI settings and end-user documentation. You want to reuse everything. Now, I will focus on DC interfaces only. Here are the interfaces that are related to Tasks:
假设你有两套领域构建 任务和安全权限。这两个他们包含DC接口,领域逻辑,控制器,行为,界面设置和终端用户文档。下面是有关任务的接口:

[DomainComponent]

public interface ITask {

    string Subject { get; set; }

    ITaskOwner AssignedTo { get; set; }

}

[DomainComponent]

public interface ITaskOwner {

    IList<ITask> Tasks { get; }

}

The developer, who designed this component, made it independent from the User concept. A Task can be assigned to any object that implements the ITaskOwner.
开发者,谁设计了这个组件,使它和用户概念无关。一个任务可被分配给任何对象实现ITaskOwner.

Here are the interfaces that define  Owership Security:
这里是定义权限的接口:

[DomainComponent]

public interface ISecuredItem {

    ISecurityOwner Owner { get; set; }

}

[DomainComponent]

public interface ISecurityOwner {

    bool IsManager { get; set; }

}

Here, a user can only see his/her own items, if he/she has the IsManager property set to false. The developer, who designed this component, made it independent from  other components again.
这里,一个用户仅能看到他自己的项目,如果他设置IsManager属性为false。开发者,谁设计了这个组件,使他再次与其他组件不同。

Now, you want to assemble your own system out of these components. You want to have Tasks  secured  using  Ownership Security. So, you  declare combined domain components and register them as entities in the following manner:
现在,你想对这些部件组装成你自己的系统。你想拥有Tasks权限。因此,你定义合并领域组件,以下列方式当做实体注册他们:

[DomainComponent]

public interface IUser : ITaskOwner, ISecurityOwner {

}

 

[DomainComponent]

public interface ISecuredTask : ITask, ISecuredItem {

}

[Test]

public void TestOwner() {

    RegisterDC<IUser>();

    RegisterDC<ISecuredTask>();

    IUser user = CreateObject<IUser>();

    ISecuredTask task = CreateObject<ISecuredTask>();

    task.Owner = user;

}

What will be generated from these components? The answer is  quite obvious. The IUser and ISecuredTask interfaces will be implemented and mapped to the following tables:
将用这些组件生成什么?答案很明显。IUserISecuredTask接口将被实现,映射到下面表:

This structure allows you to assign different Users  to  Task object's AssignedTo and Owner  properties. But, what if you want  these  properties  always set to the same User? For this purpose, I could provide  additional logic  that would synchronize both these properties. However, I would still have two associations in the database, which I don’t need. I want to have a table structure like this:

I need a way to tell the XpoBuilder that I want the ITask.AssignedTo and ISecuredItem.Owner to be mapped to the  same column/property. Remember, I can not change the source  code of the Tasks and Ownership Security components. I can only change  my IUser and ISecuredTask. So, to  implement the Isecured Task  in accordance to  my requirement, I  can write something like this:
我需要一种方法告诉XpoBuider,Itask.AssignerToIsecuredItem.Owner映射到相同的列/属性。记得,我不能更改TasksOwnership安全组件。我仅能更改我的IuserIsecuredTask。因此,按照需求实现IsecuredTask,我可以这样写:

public class SecuredTask : XPObject, ISecuredTask  {

    public User Owner 

    ITaskOwner ITask.AssignedTo {

        get { return (ITaskOwner)Owner; }

        set { Owner = (User)value; }

    }

    ISecurityOwner ISecuredItem.Owner {

        get { return (ISecurityOwner)Owner; }

        set { Owner = (User)value; }

    }

}

Here, I  build a new association and explicitly implement both the ITask.AssignedTo and ISecuredItem.Owner properties.
It'd be much easier, if I could  tell  the XpoBuilder something like this:
这里,我建立一个新的关联,显示实现Itask.AssignedToIsecuredItem.Owner属性。如果能以以下方式告诉XpoBuiler,这将容易很多。

[DomainComponent]

public interface ISecuredTask : ITask, ISecuredItem {

    [Implements("ITask.AssignedTo", "ISecuredItem.Owner")]

    new IUser Owner { get; set; }

}
This would indicate that I have a new association between a SecuredTask and  User, and I want the ITask.AssignedTo and ISecuredItem.Owner properties to be “mapped'” to it. But something tells me that this would break associations. For instance, when I try to get the User.Tasks, XPO won’t be able to find a back reference (it expects the AssignedTo property, but it is non-persistent). So again, I had to  beg  the XPO team for some alias magic.
这将显示,一个SecuredTaskUser之间有一个新的关联,我想使Itask.AssignedToIsecuredItem.Owner属性映射它。但是有些事情告诉我这就切断关联。例如,当我试着获取User.Tasks,XPO不能发现一个后引用(它预期的AssignedTo属性,但,它没持久化)。如此反复,我不得不祈求XPO团队的一些别名魔术。

Please, XPO team, make my (our?) dream come true!
请,XPO团队,使我们的梦想成真!

 

欢迎转载,转载请注明出处:http://www.cnblogs.com/Tonyyang/

原文地址:https://www.cnblogs.com/Tonyyang/p/1945078.html