Skip to content

Commit

Permalink
Fixed #225
Browse files Browse the repository at this point in the history
  • Loading branch information
scott-xu committed Sep 16, 2017
1 parent 8d5e5c1 commit 1a10672
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/Ninject/Infrastructure/Language/ExtensionsForAssembly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ public static bool HasNinjectModules(this Assembly assembly)
/// <returns>The loadable <see cref="INinjectModule"/>s</returns>
public static IEnumerable<INinjectModule> GetNinjectModules(this Assembly assembly)
{
return assembly.ExportedTypes.Where(IsLoadableModule)
.Select(type => Activator.CreateInstance(type) as INinjectModule);
return assembly.IsDynamic ?
Enumerable.Empty<INinjectModule>() :
assembly.ExportedTypes.Where(IsLoadableModule)
.Select(type => Activator.CreateInstance(type) as INinjectModule);
}

private static bool IsLoadableModule(Type type)
Expand Down

1 comment on commit 1a10672

@ewmccarty
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm newish to this .. I'm using Ninject v3.3.4 and AutoMapper v6.2.1

In a Database Layer I'm using the Factory Pattern as follows

return new PersonRepository() as IRepository<T, TId, TKey>;

where

public class PersonRepository : Repository<WEI.Models.Dto.Person, global::System.Int64?, global::System.Int64?>, I.IPersonRepository

and

    public class Repository<T, TId, TKey>
    {
        public AutoMapper.IMapper AutoMapper { get; set; }
        public DbContext DbContext { get; set; } // Entity Framework v6.2.0 referenced in an external Project

        /// <summary>
        /// Uses Ninject Dependency Injection
        /// Instantiates Ninject Kernel and loads all Assembly owned Ninject Modules
        /// </summary>
        /// <see cref="WeiApiDatabase.AutoMapperNinjectModule"/>
        protected Repository()
        {
            var kernel = new Ninject.StandardKernel();
            kernel.Load(global::System.Reflection.Assembly.GetExecutingAssembly());
            this.DbContext = kernel.Get<global::System.Data.Entity.DbContext>();
            this.AutoMapper = kernel.Get<AutoMapper.IMapper>();
        }
)

and finally

using System.Linq;
using System.Reflection;
using Ninject;

namespace WeiApiDatabase
{
    /// <inheritdoc />
    /// <summary>
    /// Ninject module for AutoMapper
    /// Reference http://automapper.readthedocs.io/en/latest/Dependency-injection.html
    /// </summary>
    public class AutoMapperNinjectModule : global::Ninject.Modules.NinjectModule
    {
        public override void Load()
        {
//            this.Bind<AutoMapper.IValueResolver<VDM.bHRRM, WEI.Models.Person, bool>>().To<Dto.PersonRepository>();

            AutoMapper.MapperConfiguration mapperConfiguration = this.CreateConfiguration();
            this.Bind<global::AutoMapper.MapperConfiguration>().ToConstant(mapperConfiguration).InSingletonScope();

            // This teaches Ninject how to create automapper instances say if for instance
            // MyResolver has a constructor with a parameter that needs to be injected
            this.Bind<AutoMapper.IMapper>().ToMethod(ctx =>
                new AutoMapper.Mapper(mapperConfiguration, type => ctx.Kernel.Get(type)));
        }

        /// <summary>
        /// Adds all profiles in the current assembly and referenced projects
        /// </summary>
        /// <returns></returns>
        /// <see cref="WeiApiDatabase.Models.Mapping.ViewpointRepositoryAutoMapperProfile"/>
        private global::AutoMapper.MapperConfiguration CreateConfiguration()
        {
            **var assembliesToScan = System.AppDomain.CurrentDomain.GetAssemblies();
            var allTypes = assembliesToScan.SelectMany(a => a.ExportedTypes).ToArray();

            var profiles =
                allTypes
                    .Where(t => typeof(AutoMapper.Profile).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo()))
                    .Where(t => !t.GetTypeInfo().IsAbstract);**

            var config = new global::AutoMapper.MapperConfiguration(cfg =>
            {
                // Add all profiles in current assembly
                cfg.AddProfiles(this.GetType().Assembly);

                **//Add all assemblies in the CurrentDomain; i.e. Referenced Projects
                foreach (var profile in profiles)
                {
                    cfg.AddProfile(profile);
                }**
            });

            return config;
        }
    }
}

Everything was working so long as I was using only AutoMapper Profiles within the Database Access Layer, but when I moved one of the Profiles into a Common DTO/Utility Assembly and introduced the bolded code in CreateConfiguration() the Unit tests began throwing

Message: Test method WeiApiDatabaseTests.Models.Dto.PersonRepositoryTests.PersonRepositoryGetByIdTest threw exception: 
System.NotSupportedException: The invoked member is not supported in a dynamic assembly.

The bolded code in CreateConfiguration() was extracted from
How to Initialize AutoMapper Profiles in referenced project DLLs in ASP.Net webapp

This eventually researching the issue led me to your commit above. As it's seems you have solved the issue, I conclude that my implementation in the Repository() Constructor is flawed. But I"m not sufficiently familiar with Ninject to identify a fix. Can you make a recommendation to get me going n the right direction?

Please sign in to comment.