This is a migrated thread and some comments may be shown as answers.

OpenAccess Fluent With Seperate Assemblies

5 Answers 131 Views
Data Access Free Edition
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Kolie
Top achievements
Rank 1
Kolie asked on 02 Nov 2012, 05:46 PM
Hi my project currently works with EntityFramework to provide the database access and works to a degree. I am looking at converting it over to OpenAccess but am running into some issues.

My project is separated into multiple assemblies, Project.Core and Project.DAL being the relevant modules, which are accessed from Project.Web. In the Core project I have all my base entities defined, like so:

using System.Collections.Generic;
using Project.Core.Domain.Localization;
 
namespace Project.Core.Domain.Global
{
    public class Country
        : IEntity, ILocalizedEntity
    {
        private readonly IList<StateProvince> stateProvinces = new List<StateProvince>();
 
        public virtual string Name { get; set; }
        public virtual string TwoLetterIsoCode { get; set; }
        public virtual string ThreeLetterIsoCode { get; set; }
        public virtual int NumericIsoCode { get; set; }
        public virtual bool IsPublished { get; set; }
        public virtual int DisplayOrder { get; set; }
 
        public virtual IList<StateProvince> StateProvinces
        {
            get { return stateProvinces; }
        }
 
        #region IEntity Members
 
        public virtual long Id { get; set; }
 
        #endregion
    }
}

In the DAL project I have my mappings defined like so:

using Project.Core.Domain.Global;
using Telerik.OpenAccess.Metadata;
using Telerik.OpenAccess.Metadata.Fluent;
 
namespace Project.DAL.Mapping.Global
{
    public class CountryConfiguration
        : MappingConfiguration<Country>, IDatabaseMap
    {
        public CountryConfiguration()
        {
            MapType(x => new
                             {
                                 IsPublished = x.IsPublished,
                                 Name = x.Name,
                                 NumericIsoCode = x.NumericIsoCode,
                                 ThreeLetterIsoCode  = x.ThreeLetterIsoCode,
                                 TwoLetterIsoCode = x.TwoLetterIsoCode,
                                 DisplayOrder = x.DisplayOrder
                             }).ToTable("Country");
            HasProperty(x => x.Id).IsIdentity(KeyGenerator.Autoinc);
             
             
        }
    }
}
 
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Telerik.OpenAccess.Metadata.Fluent;
 
namespace Project.DAL.Mapping
{
    public class ProjectMetadataSource : FluentMetadataSource
    {
        private readonly IList<MappingConfiguration> configurations = new List<MappingConfiguration>();
 
        protected override IList<MappingConfiguration> PrepareMapping()
        {
             
            var assemblies = new List<Assembly>(AppDomain.CurrentDomain.GetAssemblies());
 
            foreach (var assembly in assemblies)
            {
                var stuff = assembly.GetTypes().Where(type => !string.IsNullOrEmpty(type.Namespace)).Where
                    (
                        type =>
                        type.BaseType != null && type.GetInterfaces().Contains(typeof (IDatabaseMap)));
                foreach (var type in stuff)
                {
                    var map = Activator.CreateInstance(type) as MappingConfiguration;
                    configurations.Add(map);
                }
            }
 
 
            return configurations;
        }
    }
}


The problem I then run into is an exception at runtime when creating the schema:

"No metadata has been registered for class 'Project.Core.Domain.Global.Country, Project.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. (This usually indicates, that either this class is not declared persistent or it is declared persistent but not enhanced. The class was loaded from file:///C:/Data/Project/Project.Web/bin/Project.Core.DLL.)

The Core, DAL, and Web modules all have in their respective csproj the line:
<Import Condition="Exists('$(MSBuildExtensionsPath)\OpenAccess.targets')" Project="$(MSBuildExtensionsPath)\OpenAccess.targets" />

After some research it would seem the Enhancer isn't running for certain modules, or the separation of the modules may be an issue. Taking the Country.cs file into the DAL module does resolve the issue, which then will complain about the other Entity objects that have not been moved.

I am unsure how to move forward with regards to resolving this issue. I would like to keep the separation of modules in my project. Any input towards a solution is appreciated!


5 Answers, 1 is accepted

Sort by
0
PetarP
Telerik team
answered on 06 Nov 2012, 04:14 PM
Hi Kolie,

 Currently that is not supported. You must have the mappings in the same assembly as the classes reside in. You can however keep all the data access logic in a separate DAL class but the actual mappings for the classes should be in your core assembly.

Regards,
Petar
the Telerik team
Telerik OpenAccess ORM Meets ASP.NET Web API. Read more.
0
Kolie
Top achievements
Rank 1
answered on 06 Nov 2012, 05:41 PM
I moved the IDatabaseMap definition and each configuration class into the Core module. The FluentMetadataSource class is still in the DAL module. The error persists, is moving each configuration class not enough? It would seem by your reply that it is. I am still adding the configurations in PrepareMapping of the MetadataSource from the DAL.
0
PetarP
Telerik team
answered on 09 Nov 2012, 12:28 PM
Hello Kolie,

 You will need to move the source fail as well. Only the context file can remain in the DAL project. The rest should reside in the Core project.

Regards,
Petar
the Telerik team
Telerik OpenAccess ORM Meets ASP.NET Web API. Read more.
0
Kolie
Top achievements
Rank 1
answered on 09 Nov 2012, 04:36 PM
This does work however it presents me with another problem.

I have a plugins folder in my web directory. At runtime, the Core project searches this directory and loads all DLL's found within. They contain modular features that enhance the project, and are all C# modules with a particular interface. Some of these modules define new Domain objects, and the idea is that they would define their own mappings as well. The Core module would then scan the assembly for members with the IDatabaseMap interface and initialize them. The problem would be that these mappings are then contained in a seperate assembly, not the Core assembly. Is there any way for this type of scenario to work correctly with OpenAccess with some modification? I currently depend heavily on the plugin architecture and this is a must have feature.
0
PetarP
Telerik team
answered on 14 Nov 2012, 09:31 AM
Hello Kolie,

 If I understand you correctly you need to have several configurations in several different assemblies. If that is the case then I have good news for you as this is a perfectly valid and support scenario. What you need to do is have a different configuration for each assembly. Those configurations can later produce their own MetadataContainers that can be merged in one "master" container using our aggregate metadata source API. Using this you can add or remove different modules from your "master"container and thus control how the metadata will look at the end.
Please do let me know if that is what you require.

Greetings,
Petar
the Telerik team
Telerik OpenAccess ORM Meets ASP.NET Web API. Read more.
Tags
Data Access Free Edition
Asked by
Kolie
Top achievements
Rank 1
Answers by
PetarP
Telerik team
Kolie
Top achievements
Rank 1
Share this question
or