zoukankan      html  css  js  c++  java
  • XAF How to: Implement Domain Components(如何实现领域构件)

    How to: Implement Domain Components(如何实现领域构件)

     

    eXpressApp Framework > Task-Based Help > How to: Implement Domain Components

    This topic illustrates how to implement and use the Domain Components (DC). We will define several components and demonstrate how they can be combined using multiple inheritance. To learn more about DC concepts, refer to the Domain Components Basics topic.

    这个主题说明如何实现和用领域组件(DC).我们调用几个组件,演示他们如何用多继承组合。要学习更多DC原理,请参考领域组件基础主题

    Show Me(告诉我)

    The complete sample project is available in the DevExpress Code Central database at http://www.devexpress.com/example=E2194. Depending on the target platform type (ASP.NET, WinForms, etc), you can either run this example online or download an auto-executable sample.

    完成的例子项目在http://www.devexpress.com/example=E2194里。依靠平台类型(ASP.NET, WinForms等等),你也可以在线运行示例或者下载一个自动执行的示例。

    Define Domain Components and Domain Logic(定义领域构件和领域逻辑)

    Follow the steps below to define Domain Components, and implement the Domain Logic specifying the DC behavior.安装一下步骤定义领域构件,实现领域逻辑指定的DC行为。

    ·         To define a Domain Component, use the Domain Component v.10.2 template. Right-click your module project in the Solution Explorer, and select Add | New Item.... In the invoked Add New Item dialog, choose the Domain Component v.10.2 template and set the new component's name to IPerson.
    要定义一个领域构件,用领域构件V10.2模板。在项目浏览器上的模块工程上点击右键,选择添加或新建在添加新项对话框内选择领域构件V10.2模板,设置名称为IPerson.

    ·         Replace the automatically generated IPerson interface definition with the following code:
    用以下代码替换自动生成的代码:

    C#

     

    VB

     

    using DevExpress.Persistent.Base;

    // ...

    [DomainComponent, NavigationItem, ImageName("BO_Person")]

    public interface IPerson {

        [RuleRequiredField]

        string LastName { get; set; }

        string FirstName { get; set; }

        string FullName { get; }

        DateTime Birthday { get; set; }

        bool Married { get; set; }

        string SpouseName { get; set; }

    }Imports DevExpress.Persistent.Base

    ' ...

    <DomainComponent, NavigationItem, ImageName("BO_Person")> _

    Public Interface IPerson

        <RuleRequiredField> _

        Property LastName() As String

        Property FirstName() As String

        ReadOnly Property FullName() As String

        Property Birthday() As DateTime

        Property Married() As Boolean

        Property SpouseName() As String

    End Interface

    ·         Note the use of the DomainComponentAttribute. It specifies that the IPerson interface represents a Domain Component. Attributes, applicable to regular business classes and their properties (NavigationItemAttribute, ImageNameAttribute, RuleRequiredFieldAttribute, etc), can also be used with the Domain Components.
    DomainComponentAttribute要注意。它指定IPerson接口代表一个领域构件。特性,适用于日常业务类和他们的属性,也可以用到领域构件。

    ·         Replace the automatically generated PersonLogic class definition with the following code:
    用以下代码替换自动生成的代码:

    C#

     

    VB

     

    [DomainLogic(typeof(IPerson))]

    public class PersonLogic {

        public static string Get_FullName(IPerson person) {

            return string.Format("{0} {1}", person.FirstName, person.LastName);

        }

        public void AfterChange_Married(IPerson person) {

            if (!person.Married) person.SpouseName = "";

        }

    }

    <DomainLogic(GetType(IPerson))> _

    Public Class PersonLogic

        Public Shared Function Get_FullName(ByVal person As IPerson) As String

            Return String.Format("{0} {1}", person.FirstName, person.LastName)

        End Function

        Public Sub AfterChange_Married(ByVal person As IPerson)

            If (Not person.Married) Then

                person.SpouseName = ""

            End If

        End Sub

    End Class

    ·         Note the use of the DomainLogicAttribute. It indicates that the PersonLogic class represents the Domain Logic of the IPerson Domain Component. The PersonLogic class exposes methods specifying the IPerson's properties behavior. Each property's logic is recognized via method names which include prefix and target property name. So, the Get_FullName method will be executed when getting the FullName property value, and the AfterChange_Married - after modifying the Married property value. To see the list of available prefixes, refer to the Domain Components Basics topic. The FullName is the calculated read-only property and its value is a combination of the FirstName and LastName property values. The SpouseName is a dependent property - its value should be empty when the Married property value is false.
    DomainLogicAttribute要注意。它指出PersonLogic类代表IPerson领域构件的领域逻辑。PersonLogic类公开了指定的IPerson的方法行为。每个属性的逻辑通过方法名,包括前缀和目标属性名组织。因此,当操作FullName属性值执行Get_FullName方法,修改Married属性值后执行AfterChange_MarriedFullName是计算并只读属性,它的值由FirstName LastName属性值组合得到。SpouseName是一个依赖属性,当Married的属性值为false时,它的值为空。

    ·         Define the IOrganization interface with a collection of IPerson objects:
    用一个IPerson对象集合定义IOrganization接口:

    C#

     

    VB

     

    using System.Collections.Generic;

    // ...

    [DomainComponent]

    public interface IOrganization {

        string Name { get; set; }

        IList<IPerson> Staff { get; }

    }

    Imports System.Collections.Generic

    ' ...

    <DomainComponent> _

    Public Interface IOrganization

        Property Name() As String

        ReadOnly Property Staff() As IList(Of IPerson)

    End Interface

    •  

    Note(备注)

    We do not implement the Domain Logic for the IOrganization Domain Component, as it is not required in the current scenario.
    当前我们不需要给IOrganization构件实现领域逻辑。

    ·         Define the IAccount Domain Component and its Domain Logic:
    定义IAccount领域构件和它的领域逻辑:

    C#

     

    VB

     

    using DevExpress.Persistent.Base;

    using System.Security.Cryptography;

    // ...

    [DomainComponent]

    public interface IAccount {

        [FieldSize(8)]

        string Login { get; set; }

        [FieldSize(8)]

        string Password { get; set; }

    }

    [DomainLogic(typeof(IAccount))]

    public class AccountLogic {

        public static string GeneratePassword() {

            byte[] randomBytes = new byte[5];

            new RNGCryptoServiceProvider().GetBytes(randomBytes);

            return Convert.ToBase64String(randomBytes);

        }

        public static void AfterConstruction(IAccount account) {

            account.Password = GeneratePassword();

        }

    }

    Imports DevExpress.Persistent.Base

    Imports System.Security.Cryptography

    ' ...

    <DomainComponent> _

    Public Interface IAccount

        <FieldSize(8)> _

        Property Login() As String

        <FieldSize(8)> _

        Property Password() As String

    End Interface

    <DomainLogic(GetType(IAccount))> _

    Public Class AccountLogic

        Public Shared Function GeneratePassword() As String

            Dim randomBytes(4) As Byte

            CType(New RNGCryptoServiceProvider(), RNGCryptoServiceProvider).GetBytes(randomBytes)

            Return Convert.ToBase64String(randomBytes)

        End Function

        Public Shared Sub AfterConstruction(ByVal account As IAccount)

            account.Password = GeneratePassword()

        End Sub

    End Class

    ·         The FieldSize attribute behaves exactly like the XPO's Size attribute. The AfterConstruction method implements logic to be executed when the new object is created. In the sample above, it initializes the Password property.
    FieldSize特性的行为和XPOSize特性相似。当创建一个新节点时执行AffterConstruction方法实现逻辑。在上面例子中,它初始化了Password属性。

    Combine Domain Components Into a New Component (用领域构件组合一个新的构件)

    By this point, we have several Domain Components defined. These components can be packaged in an assembly, and reused in other applications as a domain library. But, in this simple example, we will use them in the same application, to demonstrate the concepts.
    至此,我们定义了几个领域构件。这些构件包装成一个程序集,在其他应用程序中作为一个领域库重用。但是,在这个简单例子中,我们在同一个应用程序中使用,目的是为了演概念。

    The interfaces support multiple inheritance. So, we can define the following domain component:
    接口支持多继承。因此,我们定义了下面领域构件:

    C#

     

    VB

     

    using DevExpress.Persistent.Base;

    // ...

    [DomainComponent, NavigationItem, ImageName("BO_Contact")]

    public interface ICustomer : IOrganization, IAccount {

    }

    Imports DevExpress.Persistent.Base

    ' ...

    <DomainComponent, NavigationItem, ImageName("BO_Contact")> _

    Public Interface ICustomer

        Inherits IOrganization, IAccount

    End Interface

     

    The ICustomer Domain Component exposes properties and utilizes logic of both IOrganization and IAccount components. You can define additional properties and logic not provided by ancestors, if required.
    ICustomer领域组件利用IOrganization IAccount构件公开了属性。如果需要,你可以定义其它属性而其他祖先逻辑没提供。

    Register the Required Domain Components in the Application(在应用程序中注册需要的领域构件)

    To get fully functional business classes, the Domain Components should be registered in the application. Edit the Module.cs (Module.vb) file. Override the ModuleBase.Setup method, as demonstrated in the following snippet:

    要得到功能完善的业务类,你要在应用程序中注册领域构件。编辑Module.cs (Module.vb)文件。覆写ModuleBase.Setup方法,情况如下片段:

    C#

     

    VB

     

    Public sealed partial class DCExampleModule : ModuleBase {

        // ...

        public override void Setup(XafApplication application) {

            if (!XafTypesInfo.IsInitialized) {

                XafTypesInfo.Instance.AddEntityToGenerate("Person", typeof(IPerson));

                XafTypesInfo.Instance.AddEntityToGenerate("Account", typeof(IAccount));

                XafTypesInfo.Instance.AddEntityToGenerate("Organization", typeof(IOrganization));

                XafTypesInfo.Instance.AddEntityToGenerate("Customer", typeof(ICustomer));

            }

            base.Setup(application);

        }

    }

    Public NotInheritable Partial Class DCExampleModule

        Inherits ModuleBase

        ' ...

        Public Overrides Sub Setup(ByVal application As XafApplication)

            If (Not XafTypesInfo.IsInitialized) Then

                XafTypesInfo.Instance.AddEntityToGenerate("Person", GetType(IPerson))

                XafTypesInfo.Instance.AddEntityToGenerate("Account", GetType(IAccount))

                XafTypesInfo.Instance.AddEntityToGenerate("Organization", GetType(IOrganization))

                XafTypesInfo.Instance.AddEntityToGenerate("Customer", GetType(ICustomer))

            End If

            MyBase.Setup(application)

        End Sub

    End Class

     

     

    Note (备注)

    With the code above, the generated classes will be derived from the XPObject class. To use another base class, use the overload of the ITypesInfo.AddEntityToGenerate method, which takes the baseClass parameter. Additionally, you can call the ITypesInfo.RegisterDomainLogic and ITypesInfo.UnregisterDomainLogic methods to manipulate the Domain Logic assignment.
    有了上面代码,生成的类起源于XPObject类。要用其它基类,请覆写ITypesInfo.AddEntityToGenerate方法,使用baseClass参数。另外,你可以调用ITypesInfo.RegisterDomainLogicITypesInfo.UnregisterDomainLogic方法操纵领域逻辑任务。

    Run the application (whether Windows Forms or ASP.NET), to ensure that you can operate the Customer and Person objects.
    运行应用程序(无论Windows Forms ASP.NET),要确保你能操作Customer Person对象。

    Close the application and invoke the Model Editor. Check that the registered Domain Components are available in the Application Model as the regular business classes.

    关闭应用程序并调用模型编辑器。检查注册领域组件在应用程序模型中作为常规业务类使用。

     

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

     

  • 相关阅读:
    Python基础-序列化模块
    dubbox
    小型供销系统
    MyBatis与SpringBoot整合案例(一)
    SpringBoot第二节
    SpringBoot第一节
    Dubbo案例SSM整合
    Dubbo生产者和消费者
    Zookeeper实战分布式锁
    Zookeeper Watcher和选举机制
  • 原文地址:https://www.cnblogs.com/Tonyyang/p/1937122.html
Copyright © 2011-2022 走看看