I'm starting a series of posts on my blog to share our experience while designing the domain component (DC) technology. It will be useful for us to know whether you like what we are doing. If not, we'll be able to correct our strategies early, before we make any mistakes.
我开始我的博客系列片分享我们在设计领域构件(DC)技术的经验。这有利于了解你对我们这样做是否感兴趣。如果不是,在我们犯错误之前,我们将及早对应调整我们的策略。
I spent last month with the XAF Core team designing the subsystem that manages type information in XAF. Until now, the framework obtained this information directly from XPO metadata, sometimes using Reflection.
我上个月和XAF核心团队用XAF设计管理数据类型信息子系统。直到现在,这个框架直接从XPO元数据获取信息,有时用反射。
The new DC technology operates with interfaces. So now, the framework needs type information about interfaces. To get this information, we can't use XPO metadata, because it does not contain it. Even if we could, we don't like this approach, because we've targeted it to abstract away from a particular ORM tool. So, we decided to write a subsystem that would allow its users to avoid dealing with the sources of the type information.
新的的DC技术用接口操作。所有,现在,这个框架需要有关接口方面的类型信息。要获取这些信息,我们不能用XPO元数据,因为它不包含它。即是我们可以,我们不喜欢这种方法,因为我们的目标是抽象方法从一个特定的ORM工具。因此,我们觉得写一个子系统,允许使用它的用户避免处理源类型信息。
When considering which approach to choose in implementing this system, Aleksey and Mike, developers from the XAF Core team, suggested an agile approach: we should refactor until the new subsystem emerges. I voted for the "Big Refactoring" approach: just write a new system, and then call it in the old methods and helpers. My approach would be faster, but it was going to lead to the crash of the entire system in a couple of weeks. This led me to do research, and partially write the type info subsystem in my private branch of XAF sources.
当我们在考虑采用哪种方法实现这个系统,Aleksey和Mike,开发者来自XAF核心团队,建议了一个敏捷方法:我们应当重构直到形成新的子系统。我投了“大重构” 方法:仅写一个新系统,然后用老方法调用它和帮手。我的方法更快,但它导致整个系统在几个星期崩溃。这让我重新研究,在我的XAF源的私有分支,部分的写类型信息子系统。
The next step was to integrate the new subsystem. Luckily, it was just after we had released the XAF 2008 vol. 2, the period when most of the XAF developers were busy fixing bugs and answering questions, and Aleksey was on vacation. This allowed me to convince Mike. We decided to integrate the new system and see how it behaved. Aleksey expected something like this from me. He even called us to ask if he should take one more week, so he wouldn’t see what we were doing. The next two weeks we were getting XAF back to the working state. Since then, we've been dealing with binding, type descriptors, complex property paths, structures, XPO dictionary (it directly affects what tables are created in the database), unit tests (should we reload type info between tests or not, you know, there are 1400+ tests), performance optimization and that sort of thing.
下一步集成这个新的子系统。幸运的是,它刚好是我们发布XAF 2008 Vol.2后,这期间,大部分XAF开发者忙于修复漏洞和回答问题,Aleksey 也已休假。这让我说服Mike.我们决定集成这个新子系统,看他如何决定。Aleksey预期一些从我以下这些话。他甚至叫我们问他是否做一个星期,因此他没看到我做了什么。下两周我得到了XAF回到了工作状态。从那时起,我们一直在处理,类型描述,复杂属性路径,结构,XPO字典(它直接影响哪些在数据库中创建的表),单元测试(),性能优化,诸如此类的事情。
Anyway, it now seems that we have the type information subsystem working. This means that we can start creating a reference application using the DC base library. We will write this library as we go.
总之,现在,看到了我们有类型信息子系统工作。这也意味着我能开始用DC基库建立一个引用引用程序。我们会写这个库。
The base of the DC approach is the runtime interface implementation. In short, we write an interface for a domain object and a "domain logic" class that contains "non-obvious" parts of the domain object's implementation. This approach provides us with the following advantages: we avoid writing obvious code, remove dependencies on a particular ORM system, inject the aspects like security or remoting flexibly, and use multiple inheritance to construct the final application from blocks.
实现DC的基本途径是运行接口。总之,我为一个领域对象写了一个接口,一个”领域逻辑”类,包括“非显而易见”的域对象的实现。这种方法有以下优点:避免写很明显的代码,移除一个特定ORM系统的依赖。注入像安全或者灵活远程,用多继承从块构建最终应用程序。
Real objects are generated from interfaces by the XpoBuilder class, written by the XPO team. This class is located in the XAF type information system. When you register an interface as an entity, the XpoBuilder implements an object for you. There is an important note here: you can build domain objects only once. After an object is generated, it cannot be modified.
真正的对象由接口从高XpoBuiler类生成,写自XPO团队。这个类位于XAF类型信息系统。当你作为一个实体注册一个接口,XpoBuilder为你实现一个对象。这里有一个重要注意事项:你只有一次建立域对象。对象生成之后不能被修改。
At this point, I have the XpoBuilder working at some level, and need to have a few things implemented in the type information system. So, let's try to build an application using the DC approach.
至此,XpoBuilder在一定程度上工作,需要用类型信息系统实现几件事情。因此,让我们试着用DC方法建立一个应用程序。
Disclaimer: The code you see here cannot be run using XAF 2008 vol.2, or earlier. Moreover, I cannot be sure it will work in the final version of DC. This is just the code that works at the moment I wrote this post.
免责声明:你在这里看到的代码不能运行使用XAF 2008年第2卷,或更早。此外,我不能肯定它会在DC的最终版本。这仅仅是代码,此刻我写这篇文章的作品。
Let’s add a Person entity to our application. In the new DC approach, the simplistic Person library element may look like this:
让我们给我们的应用程序添加一个Person实体。用新的DC方法,简化Person库可能是这样:
public interface IPerson {
string FirstName { get; set; }
string MiddleName { get; set; }
string LastName { get; set; }
string FullName { get; }
DateTime Birthday { get; set; }
Gender Gender { get; set; }
}
[DomainLogic(typeof(IPerson))]
public class PersonLogic {
public static string Get_FullName(IPerson self) {
return self.FirstName + " " + self.LastName;
}
}
Now, I need to ask XAF to generate an entity for it. For this purpose, I override the Setup method in my Module class in the following manner:
现在,我们需要XAF生成实体为它。为此,在模块类一下列方式覆写Setup方法:
XafTypesInfo.Instance.AddEntityToGenerate("Person", typeof(IPerson));
XafTypesInfo.Instance.GenerateEntities();
base.Setup(application);
}
I call the GenerateEntities method here, because at this time XAF does not performs this call inside (I've made a note to correct this).我用GenerateEntities方法,因为此时XAF不支持在里面调用(我做了一个备注纠正这个)
I run the Model Editor. As you can see, the IPerson entity is added to the BOModel node:
运行模型编辑器。如你所看,BOModel节点添加了Iperson实体:
Expanding the Views node I can see that the List and Detail Views are already generated. Oops, I cannot see a child node representing the IPerson in the NavigationItems node. I've made a note to fix this. For now, I'll add this child node manually, together with the corresponding node in the CreatableItems node:
展开试图节点,看到列表和详细视图已经生成。我不能在导航项看到Person节点存在,我做了备注修复它。现在我手动添加这个子节点在CreatableItems节点。
I run the application. In spite of the child node that I've added to the NavigationItems node, there is no "Person" in the navbar:
运行应用程序。尽管我添加了导航项目子节点,但仍没有“Person”导航项:
After some investigation it turned out that I have no permissions for the newly generated entity. The fact is that the SecuritySimple strategy assumes that we are working with objects only. Look how it gives permissions:
研究之后原来没有新生成的实体的权限。事实是SecuritySimple策略,我们认为是仅对象工作。看如何授权:
...
protected override PermissionSet ReloadPermissions() {
...
result.AddPermission(new ObjectAccessPermission(typeof(object), ObjectAccess.AllAccess));
...
}
...
}
Since an interface is not a descendant of the System.Object, I have no rights to it. I've written a unit test for XAF developers. It shows that their assumption is wrong. In order to proceed, I'll write my own SecuritySystem strategy:
由于接口不是System.Object的后代,没有给他授权。我给XAF开发者写一个单元测试。这表明他们的假定是错误的。为了继续,我写了自己的SecuritySystem策略:
protected override System.Security.PermissionSet ReloadPermissions() {
System.Security.PermissionSet result = base.ReloadPermissions();
foreach(ITypeInfo entity in XafTypesInfo.Instance.RegisteredEntities) {
result.AddPermission(new ObjectAccessPermission(entity.Type, ObjectAccess.AllAccess));
}
return result;
}
}
My Security gives all permissions to all registered entities (all persistent types). This is not a system you would like to have in a real application, but it will let me move on.
我的安全系统给所有注册的实体完全权限。这不像实际应用中的应用程序,目的为了继续执行。
Now, I run my application, and "voila":现在我运行我的应用程序,那不是?
In the next post, I'll tell you about my efforts to associate objects using the One-to-Many relationship. Now, you are free to share your ideas on this post.
在接下来的文章中,我告诉我努力用一个一对多的关系关联对象,现在,你可以自由地分享您的想法对这个文章。
欢迎转载,转载请注明出处:http://www.cnblogs.com/Tonyyang/
欢迎转载,转载请注明出处:http://www.cnblogs.com/Tonyyang/