Quantcast
Channel: eXpandFramework RSS
Viewing all articles
Browse latest Browse all 861

BLOG by Dennis Garavsky: Exposing Domain Components (DC) via OData for mobile apps

$
0
0

As you probably know, it is possible to use DC in non-XAF applications as described at http://documentation.devexpress.com/#Xaf/CustomDocument3305

So, I will use a similar approach in my XPO OData Service (you can learn more on how to create it via the wizard here). Once I created the service, I will have to modify my XpoDataServiceV3 descendant as shown below:

[JSONPSupportBehavior]
public class DataService : XpoDataServiceV3
{
static XPObjectSpaceProvider objectSpaceProvider = null;
static readonly DataService1Context serviceContext =
new DataService1Context("XpoContext",
"DevExpress.ExpressApp.DC.GeneratedClasses",
CreateDataLayer()
);
protected override UnitOfWork GetSessionCore(IObjectLayer objectLayer) {
if (objectSpaceProvider != null) {
XPObjectSpace os = (XPObjectSpace)objectSpaceProvider.CreateObjectSpace();
return (UnitOfWork)os.Session;
}
return base.GetSessionCore(objectLayer);
}
static IDataLayer CreateDataLayer() {
//Dennis: Initializing the XAF types info system per http://documentation.devexpress.com/#Xaf/CustomDocument3305
XpoTypesInfoHelper.ForceInitialize();
var typesInfo = XpoTypesInfoHelper.GetTypesInfo();
var xpoTypeInfoSource = XpoTypesInfoHelper.GetXpoTypeInfoSource();

//Dennis: These are some service classes used by XAF and DC engine internally.
typesInfo.RegisterEntity(typeof(DevExpress.ExpressApp.DC.ClassGeneration.DCIntermediateObject));
typesInfo.RegisterEntity(typeof(DevExpress.ExpressApp.Xpo.Updating.ModuleInfo));

//Dennis: Adding our entities to the business model. Take special note that in case of DC I directly referenced the DcAssembly.dll (it was generated when running XAF apps with no debugger attached).
typesInfo.RegisterEntity(typeof(DevExpress.ExpressApp.DC.GeneratedClasses.Survey));
//Dennis: Or you can use the following line to load all the types from an assembly.
//typesInfo.LoadTypes(typeof(DevExpress.ExpressApp.DC.GeneratedClasses.Survey).Assembly);

//Dennis: Initializing connection settings.
var connectionString = "Integrated Security=SSPI;Pooling=false;Data Source=(local);Initial Catalog=S170964";
var dataStoreProvider = new ConnectionStringDataStoreProvider(connectionString);
objectSpaceProvider = new XPObjectSpaceProviderThreadSafe(dataStoreProvider, typesInfo, xpoTypeInfoSource);
objectSpaceProvider.CreateObjectSpace(); // Force the objectSpaceProvider.DataLayer property initialization.
XpoDefault.DataLayer = objectSpaceProvider.DataLayer;
DevExpress.Xpo.XpoDefault.Session = null;
return XpoDefault.DataLayer;
}

Here I would like to focus on three things:

1. I initialized the static serviceContext variable and provide the namespace of our auto-generated DC entities as the second parameter: "DevExpress.ExpressApp.DC.GeneratedClasses". It is important to avoid dealing with long-named entities like "DevExpress_ExpressApp_DC_GeneratedClasses_Survey" in our consumer applications.

2. I initialized the data layer that is used by my XpoContext descendant via the static CreateDataLayer method. There I used some XAF magic, which is required for DC, because domain logic methods accept the parameters of the IObjectSpace type. If I did not use DC, then I would not use the XAF classes in my data service and rather go using pure XPO stuff.

3. I overrode the GetSessionCore to use the Session created by the XAF's ObjectSpace, again for the correct work of domain logic methods. Take special note that this virtual method is available in version 12.2.8+ only (thanks to our XPO guys for implementing my request so quickly;-)). If you want to test it right away, I have included the latest version of the DevExpress.Xpo.v12.2.Extensions assembly into the demo project I posted here.

Finally, it is also important to note that I referenced the DcAssembly.dll into my data service project. This assembly is automatically generated by XAF when running the application with no debugger attached. So, to get it, I simply run my XAF WinForms application and then copied the generated assembly into my data service project. It is possible, however, not to do this, but rather let the data service to generate these entities at runtime as shown at http://documentation.devexpress.com/#Xaf/CustomDocument3305. While it is more convenient at design and testing time (you needn't copy the updated DcAssembly.dll every time you modify your DC), I find the approach I used here more appropriate for production, because no additional overhead. Furthermore, this way you can work with regular persistent classes instead of interfaces (remember my recent talk about different types?), which may be easier for your understanding after all:

typesInfo.RegisterEntity(typeof(DevExpress.ExpressApp.DC.GeneratedClasses.Survey));

Here the Survey type is a real persistent object generated by XAF and stored in the DcAssembly.dll (see a screenshot from the Reflector for more details):

Screenshot

Finally, let me demonstrate why I created the OData service in the first place. Of course, I needed it for my mobile DXTREME application:


View on screencast.com »

You may also be interested in my other blog on a similar subject at http://community.devexpress.com/blogs/eaf/archive/2012/12/12/how-to-configure-the-xaf-middle-tier-security-service-and-deploy-it-in-the-cloud-for-further-use-by-desktop-xaf-and-mobile-dxtreme-clients.aspx (that one is a way more complex, though).

Permalink | Leave a comment  »


Viewing all articles
Browse latest Browse all 861

Trending Articles