Error activating IRepository{MyModel} - ninject

Situation:
Interfaces:
IRepository<T>
IMyModelRepository : IRepository<MyModel>
Classes:
Repository<T> : IRepository<T>
MyModelRepository : Repository<MyModel>, IMyModelRepository
Bindings:
kernel.Bind(typeof(Namespace.IRepository<>)).To(typeof(Namespace.Repository<>)).InRequestScope();
kernel.Bind(typeof(Namespace.IRepositoryInternal<>)).To(typeof(Namespace.Repository<>)).InRequestScope();
kernel.Bind(typeof(Namespace.IMyModelRepository)).To(typeof(NameSpace.MyModelRepository)).InRequestScope();
kernel.Bind(scanner => scanner
.FromAssemblyContaining(typeof(Namespace.SomeService))
.SelectAllClasses()
.Excluding<Namespace.MyModelRepository>()
.BindDefaultInterfaces()
.Configure(binding => binding.InRequestScope()));
Injection:
readonly IRepository<MyModel> _MyModelRepository; //this is the property, injection is constructor injection
Problem:
Error activating IRepository{WarningModel}
More than one matching bindings are available.
Activation path:
5) Injection of dependency IRepository{MyModel} into parameter MyModelRepository of constructor of type AnotherService
What am i missing? where is the multiple binding?
If this info is not enough, i can provide extra info.

The problem was .BindDefaultInterfaces(). It should have been .BindDefaultInterface().

Related

Changing IoC provider on an Caliburn Micro WPF Application

I've an existing WPF application based on caliburn micro MVVM pattern which was using Ideablade/cocktail for accessing to database. Now I've switched to servicestack and I was keeping on cocktail just for the composition pattern. Since I've noticed it takes quite a bit long to start the application I've done some test and Ninject performs better.
I find extremly usefull the MEF approach of defining the Export/ImportingConstrucor approach but and I was wondering how I can have it with Ninject... is it possible?
In my current implementation I've something as
[Export(typeof(IMyInterface))]
[Export(typeof(MyFirstViewModel))]
public class MyFirstViewModel:IMyInterface
{
[ImportingConstructor]
public MyFirstViewModel(IEventAggregator eventAggregator)รน
{
}
}
I've seend that in ninject I've to define something as
mKernel.Bind<MyFirstViewModel>().To<MyFirstViewModel>();
mKernel.Bind<MyFirstViewModel>().To<MyFirstViewModel>();
Can it be automatic?
Can I also define a funct to resolve when not found?
Thanks
StackTrace :
at Caliburn.Micro.IoC.<.cctor>b__0(Type service, String key) in c:\Users\Rob\Documents \CodePlex\caliburnmicro\src\Caliburn.Micro.Silverlight\IoC.cs:line 13
at Caliburn.Micro.IoC.Get[T](String key) in c:\Users\Rob\Documents\CodePlex\caliburnmicro\src\Caliburn.Micro.Silverlight\IoC.cs:line 32
at myApp.Modules.Core.Framework.ViewModels.myAppScreenBase`1..ctor() in c:\Projects\myApp\branches\myApp-branch-20140526\myApp\Core\Framework\ViewModels\myAppScreenBase.cs:line 44
at myApp.Modules.Core.Framework.ViewModels.myAppSimpleScreen`1..ctor() in c:\Projects\myApp\branches\myApp-branch-20140526\myApp\Core\Framework\ViewModels\myAppSimpleScreen.cs:line 8
at myApp.Modules.AdE.ViewModels.CMATCLIDDelegheViewModel..ctor(IAdERepository repository, IDialogManager dialogManager, ICommonRepository commonRepository) in c:\Projects\myApp\branches\myApp-branch-20140526\myApp\Modules.AdE\ViewModels\CMATCLIDDelegheViewModel.cs:line 56
at DynamicInjector1033b54d439c44dbaa064db1c7e82f18(Object[] )
at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
at Ninject.Activation.Context.ResolveInternal(Object scope)
at Ninject.Activation.Context.Resolve()
at Ninject.KernelBase.<>c__DisplayClass15.<Resolve>b__f(IBinding binding)
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()
RepositoryExport :
public class RepositoryBindingGenerator : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
foreach (var attribute in type.GetCustomAttributes(typeof(RepositoryAttribute), false)
.OfType<RepositoryAttribute>())
{
yield return bindingRoot
.Bind(attribute.ContractType ?? type)
.To(type).InSingletonScope();
}
}
}
but I got this compile error
Error 19 Cannot implicitly convert type 'Ninject.Syntax.IBindingNamedWithOrOnSyntax' to 'Ninject.Syntax.IBindingWhenInNamedWithOrOnSyntax'. An explicit conversion exists (are you missing a cast?)
Depending on the configuration of ninject (by default its enabled) you don't need to bind a type to itself, ninject will resolve it automatically. So mKernel.Bind<MyFirstViewModel>().To<MyFirstViewModel>(); is superfluous. Remark: Creating the binding anyway also works.
However, if you want to bind Bar to IFoo or Foo to IFoo you need to bind it.
With it you can tell ninject to look for all types with an [Export] attribute and bind these.
Here comes the ninject conventions extension to the rescue. Get the ninject.extensions.conventions nuget package.
Then create a convention binding:
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.WithAttribute<ExportAttribute>()
.BindWith<ExportBindingGenerator>());
public class ExportBindingGenerator : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
foreach (var attribute in type.GetCustomAttributes<ExportAttribute>())
{
yield return bindingRoot
.Bind(attribute.ContractType)
.To(type);
}
}
}
Things get a bit more complicated when you need to also use the [ImportingConstructor] attribute to tell ninject which constructor to use. But i would suppose that you don't need it, since Ninject's auto-constructor-selection. What you can do however is replace all [ImportingConstructor] attributes with Ninject's [Inject] attribute which does exactly the same.
Notes:
You may need to use another method than .FromThisAssembly() to specify all the assemblies which contain the implementation types.
If the implementation types are not public, you need to add IncludeNonePublicTypes() to the convention.

ninject ioc with inherited base generic repository

I have a generic repository, abstract and concrete as below
public interface IGenericRepository<T> where T : class
public class GenericRepository<T> : IGenericRepository<T> where T : class
I then have an repository that inherits from this, again abstract and concrete
public interface ISkyDiveCentreRepository : IGenericRepository<DiveCentre>
public class SkyDiveCentreRepository : GenericRepository<DiveCentre>
In my ninject config I then have
kernel.Bind(typeof(IGenericRepository<>)).To(typeof(GenericRepository<>));
kernel.Bind<ISkyDiveCentreRepository>().To<SkyDiveCentreRepository>();
This is the first time I've tried to do this but am getting the error:
Error 2 The type 'UKSkyDiveCentres.DAL.imp.SkyDiveCentreRepository' cannot be used as type parameter 'TImplementation' in the generic type or method 'Ninject.Syntax.IBindingToSyntax<T1>.To<TImplementation>()'. There is no implicit reference conversion from 'SkyDiveCentres.DAL.imp.SkyDiveCentreRepository' to 'SkyDiveCentres.DAL.ISkyDiveCentreRepository'. C:SOMEPATH\UKSkyDiveCentres\App_Start\NinjectWebCommon.cs 56 13 SkyDiveCentres
Your SkyDiveCentreRepository inherits from GenericRepository<DiveCentre> and doesn't implement the ISkyDiveCentreRepository interface.
Simply explicitly implement it:
public class SkyDiveCentreRepository :
GenericRepository<DiveCentre>, ISkyDiveCentreRepository
// ^^^^^^^^^^^^^^^^^^^^^^^^ this
Without it.. you can't do simple things like this:
ISkyDiveCentreRepository repo = new SkyDiveCentreRepository();
If you can't do it.. Ninject can't either.

Ninject - Injecting singleton

I have this error when clicking a link on a site I'm creating
Error activating IEntityCache using binding from IEntityCache to EntityCache
No constructor was available to create an instance of the implementation type.
Activation path:
4) Injection of dependency IEntityCache into parameter entityCache of constructor of type AlbumRepository
3) Injection of dependency IAlbumRepository into parameter albumRepository of constructor of type AlbumService
2) Injection of dependency IAlbumService into parameter albumService of constructor of type AlbumController
1) Request for AlbumController
Suggestions:
1) Ensure that the implementation type has a public constructor.
2) If you have implemented the Singleton pattern, use a binding with InSingletonScope() instead.
EntityCache is a singleton with no public construction. So this is how I've done my Ninject bindings
kernel.Bind<IAlbumService>().To<AlbumService>();
kernel.Bind<IAlbumRepository>().To<AlbumRepository>();
kernel.Bind<IDbSetWrapper<Album>>().To<DbSetWrapper<Album>>();
kernel.Bind<IEntityCache>().To<EntityCache>().InSingletonScope();
What am I doing wrong?
EDIT
Here's my repository:
public AlbumRepository(DatabaseContext context, IDbSetWrapper<Album> dbSetWrapper, IEntityCache entityCache)
: base(context, dbSetWrapper, entityCache)
How do I pass in an IEntityCache?
EntityCache is a singleton with no public construction.
And how do you expect your DI framework to be able to instantiate this class? This cannot possibly work if your class doesn't have a default public constructor or a constructor taking arguments which are already registered in your DI.
You might need to provide the specific instance yourself if the class doesn't have public constructor:
kernel
.Bind<IEntityCache>()
.ToMethod(context => ...return your specific instance here...)
.InSingletonScope();
for example:
kernel
.Bind<IEntityCache>()
.ToMethod(context => EntityCache.Instance)
.InSingletonScope();

Cyclic dependency with Castle Windsor IoC for NHibernate ISession

I am using Castle Windsor for my IoC along with NHIbernate in an ASP.NET MVC app. It works great registered as follows (with one exception):
container.Register(Component.For<ISessionFactoryBuilder.().ImplementedBy<SessionFactoryBuilder>().LifestyleSingleton());
// Register the NHibernate session factory as a singleton using custom SessionFactoryBuilder.BuildSessionFactory method.
container.Register(Component.For<ISessionFactory>().UsingFactoryMethod(k => k.Resolve<ISessionFactoryBuilder>().BuildSessionFactory("ApplicationServices")).LifestyleSingleton());
container.Register(Component.For<IInterceptor>().ImplementedBy<ChangeAuditInfoInterceptor>().LifestylePerWebRequest());
container.Register(Component.For<ISession>().UsingFactoryMethod(k => k.Resolve<ISessionFactory>()
.OpenSession(container.Resolve<IInterceptor>())).LifestylePerWebRequest());
All is good except that for my ChangeAuditInterceptor in turn has an IAccountSession service injected which in turn has an NHibernate ISession injected...which leads to the following circular dependency exception:
Dependency cycle has been detected when trying to resolve component
'Late bound NHibernate.ISession'. The resolution tree that resulted in
the cycle is the following: Component 'Late bound NHibernate.ISession'
resolved as dependency of component
'Blah.Core.Services.AccountSession' resolved as dependency of
component 'Blah.Core.Infrastructure.Data.ChangeAuditInfoInterceptor'
resolved as dependency of component
'Blah.Core.Infrastructure.Installers.SessionFactoryBuilder' resolved
as dependency of component 'Late bound NHibernate.ISessionFactory'
resolved as dependency of component 'Late bound NHibernate.ISession'
which is the root component being resolved.
For the past couple years I've usually run with an NHibernateSessionManager which took care of plunking in the IInterceptor without causing this circular dependency issue (as opposed to this usage of a SessionFactoryBuilder which uses Castle Windsor's UsingFactoryMethod functionality).
Any suggestions for how to resolve this circular dependency? Short of starting to hack in the ISession for the AccountSession via some other means (i.e. property injection which skirts around the issue and smells as a result). I've switched the ISession injection to property injection for the AccountSession service and it works fine, but I don't like the implicit contract vs. the constructor explicit contract.
public class AccountSession : IAccountSession
{
private readonly ISession _session;
public AccountSession(ISession session)
{
_session = session;
}
public Account GetCurrentAccount() // Called by a method in ChangeAuditInterceptor
{
...
}
...etc.
Try to add a dependency on Func< ISession > in your interceptor class
public class CustomInterceptor : EmptyInterceptor
{
private readonly Func<ISession> sessionFunc;
private ISession session;
protected ISession Session
{
get
{
return session ?? (session = sessionFunc());
}
}
public CustomInterceptor(Func<ISession> sessionFunc)
{
this.sessionFunc = sessionFunc;
}
}
And registration:
container.Register(Component.For<ISession>().
LifestylePerWebRequest()
.UsingFactoryMethod(container =>
{
var interceptor = container.Resolve<IInterceptor>();
return container.Resolve<ISessionFactory>.OpenSession(interceptor);
}));
container.Register(Component.For<Func<ISession>>()
.LifestylePerWebRequest()
.UsingFactoryMethod(container =>
{
Func<ISession> func = container.Resolve<ISession>;
return func;
}));

Mapping inheritance in NHibernate 3.3

I have the inheritance described below :
public abstract class BaseEntity<TId> {....}
public abstract class ModelEntity : BaseEntity<Int32>{....}
public abstract class AuditableEntity : ModelEntity,IAuditable{....}
public class ApplicationUser : AuditableEntity{....}
public class SuperUser : ApplicationUser
I am using NHibernate 3.3 and I want to Create the mappings for that inheritance
public abstract class ModelEntityMap<TEntity> : ClassMapping<TEntity>
where TEntity : ModelEntity
{...}
public class AuditableEntityMap<TEntity> : ModelEntityMap<TEntity> where TEntity : AuditableEntity
{ ...}
public class ApplicationUserMap : AuditableEntityMap<ApplicationUser>
{...}
public class SuperUserMap : JoinedSubclassMapping<SuperUser>{...}
When the application starts and trys to set up the database it raises the following Exception :
Ambiguous mapping for SuperUser More than one root entities was found BaseEntity / ApplicationUser
Possible solutions
-Merge the mapping of root Entity in the one is representing the real root in the hierarchy
-Inject a IModelInspector with a logic to discover the real root-entity.
I was using Fluent nhibernate with the same inheritance and worked fine with SuperUserMap defined as
public class SuperUserMap : SubClassMap {...}
I am new to Nhibernate mapping by code and quite confused !!!
I believe there are two ways to solve this problem:
a) Using the concept of discriminator that identifies the type of the class stored and thereby the right object is retrieved from the database, in this case your class is mapped to a table that has all the columns plus the discriminator columns. Not sure how this works with multi-level inheritance but this is something that you can google.
b) take a look at this post on how he deals with inheritance: http://fabiomaulo.blogspot.co.nz/2011/04/nhibernate-32-mapping-by-code_13.html you might get some idea to solve your issue.
You can influence the decision whether an entity is a root entity by overriding the IsRootEntity logic of the model mapper that you use to create mappings.
Here's an example that defines the default NHibernate mapping-by-code behaviour:
var modelMapper = new ConventionModelMapper();
modelMapper.IsRootEntity((type, declared) =>
{
if (declared) return true; // Type has already been declared as root entity
return type.IsClass
&& typeof(object) == type.BaseType
&& modelMapper.ModelInspector.IsEntity(type);
});
You will have to tweak this decision logic to exclude the BaseEntity class as possible root entity.
I had this error with NHibernate 4.1.1 (May 2017), so I'm answering with how I solved it for future reference
In my case, I copied an existing mapping of an inheriting class, and forgot to change the parent mapping class to ClassMapping and encountered the same error
In other words, in your mapping class, check the parent class, make sure it is ClassMapping or JoinedSubclassMapping if it's a child class