XCRM: Marketing Campaigns and Customer support(市场营销和客户支持)
Marketing Campaigns(市场营销)
A Marketing Campaign has no relationships. However, a Lead and Opportunity may reference a Campaign:
市场营销不靠关系。然而,一个Lead和Opportunity可能来自广告:
[Test]
public void CampaignRelationships() {
RegisterDC<ILead>();
RegisterDC<ICampaign>();
RegisterDC<IContact>();
RegisterDC<IAccount>();
RegisterDC<IOpportunity>();
Generate();
ICampaign campaign = ObjectSpace.CreateObject<ICampaign>();
campaign.Name = "Playboy back cover";
ILead lead = ObjectSpace.CreateObject<ILead>();
IOpportunity opportunity = ObjectSpace.CreateObject<IOpportunity>();
lead.Campaign = campaign;
opportunity.Campaign = campaign;
}
[DomainComponent]
public interface ICampaign {
string Name { get; set; }
}
[DomainComponent]
public interface ILead {
…
ICampaign Campaign { get; set; }
}
[DomainComponent]
public interface IOpportunity {
…
ICampaign Campaign { get; set; }
}
Instead of adding the Campaign reference property to both the ILead and IOpportunity components, I could add the ICampaignResult interface and inherit the ILead and IOpportunity from it. But I think, this is overkill. However, if one more class references the Campaign, and business logic is supplied for this reference, I'll choose this approach.
Ilead和Iopportunity组件代替添加活动引用属性,我添加IcampaignResult接口,从它继承Ilead和Iopportunity.但是,我认为这是过度了。然而,如果多个类引用Campaign,业务逻辑支持引用,我将选择这种方法。
Cases (customer support incidents)(例(客户支持事件))
A Case is a record about a user's inquiry or problem. It is linked to an Account and/or a Contact. If the Contact is set, the Account is initialized from the Contact’s Account, if any:
一种情况是:一个关于一个用户的调查或问题记录。它链接一个客户,或者一个联系人。如果设置联系人,客户从联系人的客户初始化,如果有的话:
[Test]
public void CaseRelationships() {
RegisterDC<IContact>();
RegisterDC<IAccount>();
RegisterDC<ICase>();
RegisterDC<IOpportunity>();
Generate();
IContact roman = ObjectSpace.CreateObject<IContact>();
roman.FirstName = "Roman";
roman.LastName = "Eremin";
IAccount dx = ObjectSpace.CreateObject<IAccount>();
dx.Name = "DevExpress";
ICase case1 = ObjectSpace.CreateObject<ICase>();
case1.Subject = "1";
case1.Contact = roman;
Assert.IsNull(case1.Account);
ICase case2 = ObjectSpace.CreateObject<ICase>();
case2.Subject = "2";
case2.Account = dx;
Assert.IsNull(case2.Contact);
roman.Account = dx;
ICase case3 = ObjectSpace.CreateObject<ICase>();
case3.Subject = "3";
case3.Contact = roman;
Assert.AreEqual(dx, case3.Account);
}
[DomainComponent]
public interface ICase {
string Subject { get; set; }
IAccount Account { get; set; }
IContact Contact { get; set; }
}
To make this test pass we need an extra code, in addition to the interface. We need domain logic for the ICase to initialize the ICase.Account property by the ICase.Contact's Account:
要使这个测试通过我们需要一个扩展代码,附件到这个接口。我们需要领域逻辑通过Icase.Contacts的客户为Icase初始化ICase.Account属性:
[DomainLogic(typeof(ICase))]
public class CaseLogic {
public static void AfterChange_Contact(ICase self) {
if (self.Contact != null && self.Account == null) {
self.Account = self.Contact.Account;
}
}
}
Here is how we are planning to add domain logic to the classes that are generated by the XpoBuilder. We are going to use naming conventions. If the XpoBuilder finds a method named “AfterChange_XXX”, it tries to call this method in the generated setter of a XXX property. We'll probably add the attribute-based binding in the future.
这是如何用计划给这个类添加领域逻辑用XpoBuilder生成的类。我们打算使用明明约定。如果XpoBuilder发现命名为“AfterChange_XXX”的方法,它试着在生成的一个XXX属性的Setter内调用方法。我们将来可能添加基于特性的绑定。
A Case should have a human-readable ID that can be used in communications to quickly reference the Case. This ID should be generated only once, when a new object is beeing created. In addtion, the ID property should be read-only, but persistent.
一种情况应当有一个人可读ID,它可用于沟通,快速引用Case.当新建一个对象时,这个ID应当只生成一次,另外,这个ID属性也应当只读,但可以持久化。
Here is one more DC design challenge: how domain logic can specify the initial value of a read-only property? Should I add an AfterConstruction method to the business logic to set a value? But in this instance, I'll have to provide some system interfaces to call the ID’s setter. So, I think it is better to implement the Init_XXX domain logic methods that will allow you to set a property's initial value for a newly created object.
这里有一个DC设计挑战:如何能用DC逻辑给一个只读属性指定一个初始值?应当给业务逻辑添加一个AffterConstruction方法设置一个值?但是,在这种情况下,我提供了一些系统接口来调用ID的setter,我想这能较好实现Init_XXX领域逻辑方法,允许你在新建一个对象时设置属性的初始值。
Since the ID property doesn't have a setter, it won't be persisted by default. To make this property persistent, I've decided to decorate it with the Persistent Dc attribute. It could make sence to call this attribute Persistent, but in XAF this name conflicts with XPO’s Persistent attribute. So, it will be Persistent Dc for now, and we will see what to do with it later.
由于这个ID属性没有一个setter,默认不能被持久化。要使这个属性持久化,我决定用持久化DC特性修饰它。它调用特性持久化是有意义的。但,在XAF中这个名字与XPO的持久化特性冲突。因此,目前持久化DC,我们将看到用它之后做了什么.
[DomainComponent]
public interface ICase {
[PersistentDc]
string ID { get; }
…
}
[DomainLogic(typeof(ICase))]
public class CaseLogic {
public static string Init_ID(ICase self) {
//ToDo: Change to "select count(*)+1 from case" analog
return Guid.NewGuid().ToString();
}
…
}
This is a very simplistic implementation. I will return with a more realistic code, as soon we have a proper infrastructure.
这是一个非常简单的实现。我要回到一个更现实的代码,不久,我们将有一个适当的基础架构。
欢迎转载,转载请注明出处:http://www.cnblogs.com/Tonyyang/
欢迎转载,转载请注明出处:http://www.cnblogs.com/Tonyyang/