OpenAccess Fluent With Seperate Assemblies

6 posts, 0 answers
  1. Kolie
    Kolie avatar
    4 posts
    Member since:
    Oct 2012

    Posted 02 Nov 2012 Link to this post

    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!


  2. PetarP
    Admin
    PetarP avatar
    754 posts

    Posted 06 Nov 2012 Link to this post

    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.
  3. DevCraft banner
  4. Kolie
    Kolie avatar
    4 posts
    Member since:
    Oct 2012

    Posted 06 Nov 2012 Link to this post

    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.
  5. PetarP
    Admin
    PetarP avatar
    754 posts

    Posted 09 Nov 2012 Link to this post

    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.
  6. Kolie
    Kolie avatar
    4 posts
    Member since:
    Oct 2012

    Posted 09 Nov 2012 Link to this post

    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.
  7. PetarP
    Admin
    PetarP avatar
    754 posts

    Posted 14 Nov 2012 Link to this post

    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.
Back to Top
DevCraft banner