Search This Blog

Saturday, July 19, 2014

How to customize the underlying database provider options and data access behavior in XAF


I just wanted to repost my recent update to the corresponding article, because this information can interest some advanced XAF users.

IMPORTANT NOTE

This article describes some advanced customization techniques and low-level entities of the framework with regard to data access, which may be required in complex scenarios only.
So, if you just want to change the connection string, e.g. to use the Oracle instead of the Microsoft SQL Server database, then you would better refer to the Connect an XAF Application to a Database Provider article and documentation on your database provider instead. The XAF integration of supported ORM libraries is also described in the Business Model Design section of the framework's documentation.

Introducing IObjectSpaceProvider and IObjectSpace

XAF accesses data from a data store through special abstractions called - IObjectSpaceProvider and IObjectSpace.
The IObjectSpace is an abstraction above the ORM-specific database context (e.g., the DBContext used in Entity Framework or the Session in XPO) allowing you to query or modify data.
The IObjectSpaceProvider is a provider/creator of IObjectSpace entities, which also manages which business types these IObjectSpace are supposed to work with, how to set up the underlying connection to the database, create and update it and other low level data access options.



An XafApplication can use one or several IObjectSpaceProvider objects at the same time, and you can access this information through the XafApplication.ObjectSpaceProvder or XafApplication.ObjectSpaceProviders properties. Check out these help links to learn more on how to plug in custom IObjectSpaceProvider objects a well.

There are several built-in implementations of the IObjectSpaceProvider and IObjectSpace interfaces in our framework, which are usually specific to a target ORM (Entity Framework or XPO). I suggest you check out the source code of the default framework classes to better understand the role of the IObjectSpaceProvider:
...\DevExpress.ExpressApp.Xpo\XPObjectSpaceProvider.cs
...\DevExpress.ExpressApp.EF\EFObjectSpaceProvider.cs 

Typical customization considerations

You may want to provide a fully custom IObjectSpaceProvider implementation or inherit from the built-in implementors when you want to customize how data access is performed for a chosen ORM.
Below is a list of typical scenarios where a custom IObjectSpaceProvider may be required:
1. How to use XPO caching in XAF
2. How to prevent altering the legacy database schema when creating an XAF application
3. How to connect to remote data store and configure WCF end point programmatically
4. How do I change the default schema in the database
5. How to use a custom ObjectSpace throughout the application by handling the CreateCustomObjectSpaceProvider event?


In most cases, it is not required to implement the IObjectSpaceProvider interface from scratch since you can inherit from existing implementors or customize/just their parts.

XPO-specific customizations

1. Implementing IXpoDataStoreProvider
For instance, in XPO one of such replaceable parts is the IXpoDataStoreProvider interface, which enables you to provide a custom or configured IDataStore object, which is used for underlying data access with this ORM:
[C#]
public interface IXpoDataStoreProvider { IDataStore CreateWorkingStore(out IDisposable[] disposableObjects); IDataStore CreateUpdatingStore(out IDisposable[] disposableObjects); string ConnectionString { get; } }

In its turn, XAF provides several ready to use implementations of this interface for most popular scenarios: 
1. ConnectionDataStoreProvider - can provide IDataStore by the IDbConnection object;
2. ConnectionStringDataStoreProvider - can provide IDataStore by just connecting string information;
3. MemoryDataStoreProvider - DataSet based in-memory IDataStore providers.

Technically, such an IXpoDataStoreProvider part is passed into the XPObjectSpaceProvider constructor as a parameter, which means that you can just customize it instead of re-implementing the whole XPObjectSpaceProvider logic.
Refer to the ...\DevExpress.ExpressApp.Xpo\XPObjectSpaceProvider.cs file within the XAF source code to better understand the role of this part.

2. Overriding XPO connection or database providers
To learn more on this approach, check out the Database Systems Supported by XPO help topic and 
How to create a custom XPO connection provider and then use it in an XAF application article in particular.


To learn more on customizing data access settings for XPO, please refer to the corresponding product documentation: Data Access Layer.

4 comments:

  1. Hi, Dennis
    great post to read,
    just i wonder if you can make a post or give us an example of how to implement a custom multi-datastore provider with simultaneous connections to different sources (databases, services..) especially in server-client fashion, it'll be of great help since data could come from many sources today.
    thanks and great post again :)

    ReplyDelete
  2. @UnKnOwN: Thank you for your feedback. An example of a provider that can connect to several databases is given at https://www.devexpress.com/Support/Center/Example/Details/E1150
    There is also an alternative solution that does not require creating a custom provider at all: https://www.devexpress.com/Support/Center/Example/Details/E4896
    As for connecting to services, this is a bit more work and the best example I can give you is to check out our built-in implementations of IEntityStore, ITypeInfoSource, IObjectSpaceProvider, etc. in the DevExpress.ExpressApp.EF or DevExpress.ExpressApp.Xpo libraries, because basically it is similar to supporting yet another ORM layer, of course if you want it to be naturally integrated into the framework. In general, it would be great to know more on your concrete scenario, environment and other requirements before suggesting a final solution, because there may be different technical solutions. Feel free to create a ticket in the Support Center and detail your scenario there: https://www.devexpress.com/Support/Center/Question/Create - we will be glad to help you realize it.

    ReplyDelete
    Replies
    1. Hi, thanks for your replay
      about those example i've examined them well, they work fine for me but in a single machine scenario, so for me what i want is the same behavior of many data-stores to many databases in server - client mode..

      Delete
  3. If you are talking about the application server, then it should be configured the same way and using the same CreateCustomObjectSpaceProvider event or the CreateDefaultObjectSpaceProvider override, as long as ServerApplication (a descendant of the XafApplication class) is used there.

    ReplyDelete