Current filter:
                                You should refresh the page.

                                Scenario

                                This example demonstrates how to create custom XAF modules with custom business objects and logic that would work with separate databases. These modules do not depend on each other and thus can be reused in other applications as a whole.
                                Usually, the connection to the database is set up in the executable application project. Typically, it is performed in the configuration file or directly in the code of the application's designer or within the Main function/Global application class. To learn more, please check out this help topic: Connect an XAF Application to a Database Provider In this example, you will learn how to establish a connection to the database directly from your module projects.

                                Steps to implement

                                1.  Add two new custom XAF modules into a new XAF solution using the XAF Solution Wizard as  described here;

                                2. Add required persistent classes into these modules as shown in the ClassLibraryN/PersistentClassN.xx files of this example solution;

                                3. Add service ModuleInfo classes into these modules as shown in the ClassLibraryN/ModuleInfoN.xx files of this example solution;

                                4.  In YourModuleName/Module.xx files, override the Setup(XafApplication application) methods of the ModuleBase descendants to handle the CreateCustomObjectSpaceProvider event of the XafApplication class as shown in the ClassLibraryX/XafModuleN.xx files of this example solution;

                                5. Build the solution, invoke the Module Designer for the platform-agnostic module (YourSolutionName.Module/Module.xx), and drag the created custom modules from the Toolbox:

                                Alternatively, you can add the same modules via the Application Designer invoked for the executable projects (as demonstrated in this example).

                                6. Declare connection strings in the configuration files of your application as shown in the TwoXpoModelsForDifferentDatabases.Web\Web.config and TwoXpoModelsForDifferentDatabases.Win\App.config files (see ConnectionStringDatabaseX under the element). These connection strings are used in the modules via the ConfigurationManager.ConnectionStrings API, but you can always modify the way your modules obtains this data.

                                Important notes

                                1.  Each module has a single static XPObjectSpaceProvider instance, which is initialized only once during the application life cycle. The e.IsObjectSpaceProviderOwner property should be set to false to prevent the application from disposing the providers.

                                2. Each ModuleUpdater class checks whether it is valid to create initial data of a certain type from this module via the IObjectSpace.CanInstantiate method.

                                3. Business classes linked to different ObjectSpaceProviders are considered to be isolated from each other and thus cannot have direct links between them, e.g., there is an association between two classes. Consider using the How to prevent altering the legacy database schema when creating an XAF application or alternative solutions if you need interlinks between classes from different data stores.

                                4. If several XPObjectSpaceProvider objects are connected to the same database, then it would be necessary to additionally map the service XPObjectType class to different tables in each XPDictionary. You can do this in the application_CreateCustomObjectSpaceProvider method by adding DevExpress.Xpo.PersistentAttribute with a modified mapping:

                                [C#]
                                ... XPClassInfo ci = typeInfoSource1.XPDictionary.GetClassInfo(typeof(XPObjectType)); if (ci != null) { ci.RemoveAttribute(typeof(PersistentAttribute)); ci.AddAttribute(new PersistentAttribute("Service_XPObjectType1")); } ...

                                5.  Domain Components (DC) cannot be used with this approach, because the XpoTypeInfoSource constructor expects a list of entity types as a parameter, which is not known at this moment. You cannot call the RegisterEntity/GenerateEntities methods of the XafTypesInfo class to obtain this list either, because in this case the types will be registered for all XpoTypeInfoSource objects within the application.

                                6. To manipulate objects, create an object space using the XafApplication.CreateObjectSpace(Type) method passing the Type argument. The database to which the created object space is connected depends on the passed type.

                                See also:
                                How to prevent altering the legacy database schema when creating an XAF application

                                Files to look at:

                                ModuleInfo1.cs (VB: ModuleInfo1.vb)
                                PersistentClass1.cs (VB: PersistentClass1.vb)
                                XafModule1.cs (VB: XafModule1.vb)
                                ModuleInfo2.cs (VB: ModuleInfo2.vb)
                                PersistentClass2.cs (VB: PersistentClass2.vb)
                                XafModule2.cs (VB: XafModule2.vb)