So I've wired up my open generic plugin in StructureMap like so
scan.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
But still get the dreaded
No Default Instance defined for PluginFamily KharaSoft.Utils.IRepository`1[[KharaSoft.App.Core.DomainObject, KharaSoft.App.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]
I debug after the Container is initialized and see that it does indeed have an instance of RepositoryBase<> registered so it knows what I want done, but it won't close it for me. Is there something I'm missing here?
It's hard to workout without seeing the full Scan code or your project layout. There are a few default steps I normally go through when I have this issue.
Ensure you have
scan.WithDefaultConventions()
Ensure that the assembly containing the Repository classes is included in the scan:
x.AssemblyContainingType(typeof(UserRepository));
Ensure that you have the correct implementations in place:
IRepository<User>
has matching
Repository<User>
Hopefully something amongst this advice might help you find the issue.
So I'm not sure if this is the "best" way but this is what I found that works. I had to explicitly register the open implementation of the plugin like this:
ObjectFactory.Initialize(
x =>
{
x.Scan(scan =>
{
scan.Assembly(typeof (IRepository<>).Assembly);
scan.WithDefaultConventions();
});
x.For(typeof (IRepository<>)).Use(typeof (RepositoryBase<>));
x.For<IUnitOfWork>().Use<MyDataContext>();
});
return ObjectFactory.Container;
See I didn't want to close the generic directly in all cases. So now my MVC controller can take a dependency like so
public PlayerController(IRepository<Player> players)
{
Players = players;
}
And StructureMap will close the dependency with an instance of RepositoryBase
Related
My question is really a repeat of an old question posted here:
Ninject 2.2 multiple bindings
It seems someone was going to deal with this back in 2011. Does anyone know if there is some way to turn off such warnings in Ninject? Or some other workaround?
EDIT
In response to #BatteryBackupUnit, here is my exact problem:
I have multiple libraries... and in my core library, I do something like this:
Find all assemblies referenced by the host application (including the host)
Find all types inheriting from IDependency from all those assemblies.
Automatically register all of those as transient
Then from another library (which may or may not be referenced by the host app), I have this:
Kernel.Bind<IDbContextFactory>().To<DbContextFactory>().InSingletonScope();
Here IDbContextFactory is also an IDependency, so it got loaded already by the core library and now I register it here but with a different scope (singleton).
From experience (and having tested it earlier) I know this is no problem in Autofac, but Ninject gives me that error message about having already registered it.
Ideally it would be better to just override any previous registrations... "cascade style" (for lack of a better phrase)..
Ninject does now support overriding open generic bindings with more specific ones.
For Example:
public interface IFoo<T> { }
public class Foo<T> : IFoo<T> { }
public class StringFoo : IFoo<string> {}
used like:
var kernel = new StandardKernel();
kernel.Bind(typeof(IFoo<>)).To(typeof(Foo<>));
kernel.Bind<IFoo<string>>().To<StringFoo>();
var intFooInstance = kernel.Get<IFoo<int>>();
var stringFooinstance = kernel.Get<IFoo<string>>();
Works.
However, if you're not talking about open generic bindings, ninject 3 still handles multi bindings the same as ninject 2.2.
In most scenarios you can work around this by using contextual bindings. Okay i would not exactly call it a workaround, i would call it good design.
In general this is described here: https://github.com/ninject/ninject/wiki/Contextual-Binding
A simple way would be to specify the binding using a name. This requires one binding for the specified one and allows only one, too.
See: https://github.com/ninject/ninject/wiki/Contextual-Binding#simple-constrained-resolution-named-bindings
It is also possible to define a "default" binding like .Bind<IFoo>().To<Foo>(); and special case bindings with the .When(...) syntax, like:
.Bind<IFoo>().To<SpecialFoo>().When(ctx => ...)
See https://github.com/ninject/ninject/wiki/Contextual-Binding#specifying-constraints-on-the-type-binding-using-arbitrary-elements-of-the-resolution-request-context
If you show us your concrete problem we might be able to provide a more concrete solution.
I'm trying to configure my Object Mapper without knowing which mapper I'm using. :/
This might sound a bit strange. The reason for this is that I'm trying out the Onion Architecture so my UI cannot know about my Object Mapper located in my Infrastructure. See this solution for an example.
I'm having some trouble figuring out how I should "delegate" the none default mapping behavior.
Stuff like:
Mapper
.CreateMap<MyModel, MyDestViewModel>()
.ForMember(
dest => dest.SomeDestinationProperty,
opt => opt.MapFrom(src => src.SomeSourceProperty)
);
I've setup a class in my MVC project which is called from Global.asax and this is where I want to configure my mappings.
public static class MapConfig
{
public static void RegisterMaps()
{
}
}
I was thinking I could do something like the following. (IMapper is a self defined interface located in Domain)
public static void RegisterMaps(HttpConfiguration config)
{
var mapper = config.DependencyResolver.GetService(IMapper);
mapper.CreateMap<MyModel, MyViewModel>();
}
Now... how would I go about setting up special behavior like the .ForMember? Keeping in mind that it cannot be AutoMapper specific.
I was thinking something along these lines mapper.CreateMap<MyModel, MyViewModel>(Expression<Func<T>>) where the Func would do some black magic that I cannot figure out right now :( - Am I on the right path or have I missed something essential?
Onion Architecture isn't about the configuration being implementation-agnostic, it's about the execution.
Just create an IMapper interface for the execution of mappings, but don't worry about the configuration. This applies to your ORM, IoC container and everything else.
Also, Onion Architecture isn't about project structure, it's about the direction of your dependencies. Just call CreateMap in your UI. You can then define an IMapper interface all the way down in Core, with the other pieces implementing a version that delegates to AutoMapper.
you're abstracting away useful functionality that will cost you more time than you initially realize. Why not spend the time choosing a mapper and sticking with it?
Why is it so important that your UI doesnt know about your mapper? Assuming that you are using MVC, you are going to be flexing a lot of your chosen mappers functionality to flatten our your domain models to view models anyway.
Its the same kind of nonsense where people use generic repository implementations 'just in case' they decide to switch ORM mid project.
Choose your infrastructure carefully and stick with it.
I have a controller that takes an instance of ICustomerService. The constructor for one of my implementations (ok, the only implementation atm) takes an array of ICustomerExporter instances.
I'm registering all implementations of ICustomerExporter using the following code:
_container.Register(AllTypes
.FromAssembly(typeof(ICustomerExporter).Assembly)
.BasedOn<ICustomerExporter>().LifestyleSingleton());
And my DefaultCustomerService implementation looks like:
public DefaultCustomerService(ISession session, ICustomerExporter[] exporters)
{
this._session = session;
this._exporters = exporters;
}
However, when I try to run the app, I get the following error:
PM.Services.Implementation.DefaultCustomerService' is waiting for the following
dependencies: - Service 'PM.Services.ICustomerExporter[]' which was not registered.
Well pretty clearly it IS registered, I can even stop in the debugger and verify in the container's component list that the ExcelCustomerExporter implementation is there. So why am I getting this error message?
Looks like you're registering for ICustomerExporter, but I don't know that Windsor will assume that an implementation of ICustomerExporter will always satisfy your ICustomerExporter[] dependency. Have you tried registering a ICustomerExporter[] dependency also?
Just to answer this question for anyone who comes along, when registering multiple services like this, you must do 2 things:
Register the ArrayResolver with the kernel prior to registering types
Make sure to tell the kernel to use the interface as the service base.
I know the error "No parameterless constructor defined for this object" has been asked about a million times. My situation is different
I have a working app. Many many controllers and one area with lots of controllers. I just added a new area. I added a controller and then a link to that controller. NOW I get the
"No parameterless constructor defined for this object" error
I have seen and conquered this problem before but it really only happens like once every 5 months. And everytime I have totally forgotten ( repressed ) the answer.
Please help
Raif
Ok, so it seems that there are several reasons one might get this error. Not surprisingly none of them have ##$% all to do with not having a parameterless constructor. The two that I'm aware of are
1) if you are using an area and you, say, move a controller from one namespace to the new one and don't update the namespace to reflect the area you will get this error.
2) and this is my situation now, if you are injecting something into the constructor of the controller and the item you are injecting has a problem with it ( there are no instantiations, or it's not registered in your IOC registration or some other runtime error ) you will get this error.
If people can think of others they should list them here because I think there are several more causes for the error.
R
While I realize this doesn't truly answer your question, your answer helped me in my troubleshooting endeavors.
I just recently came across this same issue while using MVC Portable Areas from the MVC Contrib project. I found that any dll dependancies the portable areas had must also be included when scanning for assemblies during IOC registration, something along the lines of this:
ObjectFactory.Initialize(x => x.Scan(y =>
{
y.Assembly("PortableAreaAssemblyName");
}));
ObjectFactory.Configure(x =>
{
x.For<IClassInterfaceUsedByControllerConstructor>().Use<IntendedClassInstance>();
});
I was using a ServiceLocator which i was DIing with Unity
public ServiceLocator(IUserStore userStore, IProdcutsStore productsStore, ...etc) {}
public IUserStore UserStore
{
get { return userStore; }
}
This all worked fine, but I wanted lazy instantiation of the repositories as they have quite sparse use.
So my ServiceLocator now looks like
public ServiceLocator(IUnityContainer container) {}
public IUserStore UserStore
{
get { return (IUserStore)container.Resolve(typeof(IUserStore)); }
}
// ...etc
I'm now getting a really unhelpful ResolutionFailedException error
Resolution of the dependency failed,
type =
"DomainModel.DataServices.Interface.IUserStore",
name = "". Exception message is: The
current build operation (build key
Build
Key[DomainModel.DataServices.Interface.IUserStore,
null]) failed: The current type,
DomainModel.DataServices.Interface.IUserStore,
is an interface and cannot be
constructed. Are you missing a type
mapping? (Strategy type
BuildPlanStrategy, index 3)
Telling me my interface type cannot be instantiated because it is an interface is pretty pointless. I know it's an interface, that's why the container is supposed to be resolving it for me!
Anyway, the point to note here is that I know the type mapping in the config is fine, as when I was injecting the type interface directly instead of trying to lazy load, it resolved it with no problems.
What am I missing that means something somewhere has to change in order to lazy load this way?
Update: I am guessing what's happening here, is that when I DI the container into the ServiceLocator, the "main" container is instantiating a new container each time which is then not configured properly. I think maybe I need some way to specify that I was to pass this in as the container, rather than resolve it with a new instantiation.
You're going in a somewhat wrong direction... At first you've had a testable class that declared its dependencies in the constructor and you turned it into non-so-testable, asking for "something" inside a container... No good =(
You should either implement some factory interface for your expensive object and require it in the constructor, or (if you can) switch to Unity 2.0 and use the Automatic Factories:
public ServiceLocator(Func<IUserStore> userStoreBuilder)
//...
public IUserStore UserStore
{
get { return userStoreBuilder(); }
}
If you want to only create the instance of that object once, you can add cahcing to that property, or with .NET 4.0 you can try asking Lazy in the constructor.
P.S. Oh, yes. And answering your particualr question =) If you still want to inject an instance of your container somewhere else, you need to first register it inside itself =)
container.RegisterInstance<IUnityContainer>(container);
Fix (see comments) DO NOT register a Unity container inside itself, this will cause StackOverflowException in container.Dispose(), the correct instance will be injected as a dependency without the registration.