I am have the following row to batch register implementations:
container.Register(Types.FromAssembly(typeof (BaseBll<>).Assembly)
.BasedOn(typeof (ICrudBll<>)).WithServiceAllInterfaces());
it works on 2 classes out of 4 event though they are exactlly the same.
public interface ICrudBll<T>{} //main interface
public interface IBrandBll : ICrudBll<Brand>{}
public class BrandBll : BaseBll<Brand>, IBrandBll{}// WORKING
public interface IRoleBll : ICrudBll<Role>{}
public class RoleBll : BaseBll<Role>, IRoleBll{}// NOT WORKING
it is suppose to be injected to:
//WORKING
public class BrandController : BaseApiController<Brand>
{
public BrandController(IBrandBll bll) : base(bll)
{
}
}
// NOT WORKING
public class RoleController : BaseApiController<Role>
{
public RoleController(IRoleBll bll)
: base(bll)
{
}
}
I dont see any differences between the classes and the interfaces, but yet some works and some not. (they are all in the same assembly).
This is the ERROR:
Type CrudApp.BusinessLogic.IUserBll is abstract.
As such, it is not possible to instansiate it as implementation of service 'CrudApp.BusinessLogic.IUserBll'. Did you forget to proxy it?
Again, the IBrandBll is working and the IRoleBll not.
I made a test, and injected the failed ones explicitly, and it worked:
container.Register(Component.For<IRoleBll>().ImplementedBy<RoleBll>().LifestyleTransient());
Thanks
Try changing:
container.Register(Types.FromAssembly(typeof (BaseBll<>).Assembly)
.BasedOn(typeof (ICrudBll<>)).WithServiceAllInterfaces());
to
container.Register(Classes.FromAssembly(typeof (BaseBll<>).Assembly)
.BasedOn(typeof (ICrudBll<>)).WithServiceAllInterfaces());
The statements above will also register interfaces, and it seems you only want classes to be registered.
this is actually what worked:
var types = AllTypes
.FromAssembly(typeof (ICrudBll<>).Assembly)
.BasedOn(typeof (ICrudBll<>))
.WithService.FromInterface(typeof (ICrudBll<>));
container.Register(types);
The error clearly states the problem is with IUserBll - not shown in your code snippets.
I bet IUserBll inherits from ICrudBll, which would explain the error - try to narrow down the type selection criteria to classes, excluding the interfaces:
Types.FromAssembly(typeof (BaseBll<>).Assembly)
.BasedOn(typeof (ICrudBll<>))
returns everything, including interfaces. Try something like
Types.FromAssembly(typeof (BaseBll<>).Assembly)
.Where(t => t.IsClass)
.BasedOn(typeof (ICrudBll<>))
Related
I want to create instance of PerRequestResourceProvider using ninject InRequestScope:
public class PerRequestResourceProvider: IPerRequestResourceProvider
{
priavte readonly _perRequestResorceInstance;
public PerRequestResourceProvider()
{
_perRequestResorceInstance = new PerRequestResource();
}
public PerRequestResource GetResource()
{
return _perRequestResorceInstance;
}
}
public interface IPerRequestResourceProvider
{
PerRequestResource GetResource();
}
In my NinjectDependencyResolver:
.....
kernel.Bind<IPerRequestResourceProvider>.To<PerRequestResourceProvider>().InRequestScope();
I inject IPerRequestResourceProvider in few classes. But when I add breakpoint to PerRequestResourceProvider constructor I see that PerRequestResourceProvider is created three times during one request and not single per request. What's wrong?
Update: source code ttps://bitbucket.org/maximtkachenko/ninjectinrequestscope/src
There are two issues with your code:
Ninject is not getting initialized correctly.
You need one of the Ninject.MVCx packages (according to the MVC version you are using). To configure it correctly, see: http://github.com/ninject/ninject.web.mvc
You are injecting PerRequestResourceProvider (the class type), and not IPerRequestResourceProvider (the interface type) into HomeController, thus the .InRequestScope() defined on the IPerRequestResourceProvider binding is not taking any effect. Change the HomeController constructor to get the inteface type injected and you're good.
Ninject does not require bindings for instantiatable (non-abstract,..) classes. This is why it is not obvious when the wrong binding is used.
I am writing a library that will provide a collection of public types to its consumers.
I want to make types from this library dependency injection friendly. This means that every class needs to have a constructor through which it is possible to specify every single dependency of the object being initialized. I also want the library to adhere to the convention over configuration principle. This means that if a consumer wants the default behavior, he may use a parameterless constructor and the object will somehow construct the dependencies for itself.
In example (C#):
public class Samurai {
private readonly IWeapon _weapon;
// consumers will use this constructor most of the time
public Samurai() {
_weapon = ??? // get an instance of the default weapon somehow
}
// consumers will use this constructor if they want to explicitly
// configure dependencies for this instance
public Samurai(IWeapon weapon) {
_weapon = weapon;
}
}
My first solution would be to use the service locator pattern.
The code would look like this:
...
public Samurai() {
_weapon = ServiceLocator.Instance.Get<IWeapon>();
}
...
I have a problem with this, though. Service locator has been flagged as an anti-pattern (link) and I completely agree with these arguments. On the other hand, Martin Fowler advocates use of the service locator pattern exactly in this situation (library projects) (link). I want to be careful and eliminate the possible necessity to rewrite the library after it shows up that service locator really was a bad idea.
So in conclusion - do you think that service locator is fine in this scenario? Should I solve my problem in a completely different way? Any thought is welcome...
If you want to make life easier for users who are not using a DI container, you can provide default instances via a dedicated Defaults class which has methods like this:
public virtual Samurai CreateDefaultSamurai()
{
return new Samurai(CreateDefaultWeapon());
}
public virtual IWeapon CreateDefaultWeapon()
{
return new Shuriken();
}
This way you don't need to pollute the classes themselves with default constructors, and your users aren't at risk of using those default constructors unintentionally.
There is an alternative, that is injecting a specific provider, let's say a WeaponProvider in your case into your class so it can do the lookup for you:
public interface IWeaponProvider
{
IWeapon GetWeapon();
}
public class Samurai
{
private readonly IWeapon _weapon;
public Samurai(IWeaponProvider provider)
{
_weapon = provider.GetWeapon();
}
}
Now you can provide a local default provider for a weapon:
public class DefaultWeaponProvider : IWeaponProvider
{
public IWeapon GetWeapon()
{
return new Sword();
}
}
And since this is a local default (as opposed to one from a different assembly, so it's not a "bastard injection"), you can use it as part of your Samurai class as well:
public class Samurai
{
private readonly IWeapon _weapon;
public Samurai() : this(new DefaultWeaponProvider())
{
}
public Samurai(IWeaponProvider provider)
{
_weapon = provider.GetWeapon();
}
}
I have used the following approach in my C# project. The goal was to achieve dependency injection (for unit / mock testing) whilst not crippling the implementation of the code for a "normal use case" (i.e. having a large amount of new()'s that are cascaded through the execution flow).
public sealed class QueueProcessor : IQueueProcessor
{
private IVbfInventory vbfInventory;
private IVbfRetryList vbfRetryList;
public QueueProcessor(IVbfInventory vbfInventory = null, IVbfRetryList vbfRetryList = null)
{
this.vbfInventory = vbfInventory ?? new VbfInventory();
this.vbfRetryList = vbfRetryList ?? new VbfRetryList();
}
}
This allows DI but also means any consumer doesn't have to worry about what the "default instance flow" should be.
Is there a way in StructureMap to do this kind of repetitive mapping with one line or a convention?
For<IRepository<Mailout>>().Use<MailoutRepository>();
For<IRepository<MailServer>>().Use<MailServerRepository>();
For<IRepository<MailoutStatus>>().Use<MailoutStatusRepository>();
For<IRepository<MailoutTemplate>>().Use<MailoutTemplateRepository>();
For<IRepository<Publication>>().Use<PublicationRepository>();
For<IRepository<Recipient>>().Use<RecipientRepository>();
To map IRepository<Mailout> to MailoutRepository, use:
var c = new Container(x =>
{
x.Scan(scan =>
{
// there are other options to expand which assemblies to scan for types
scan.TheCallingAssembly();
scan.ConnectImplementationsToTypesClosing(typeof (IRepository<>));
});
});
To map IRepository<Mailout> to Repository<Mailout>, use:
var c = new Container(x =>
{
x.For(typeof (IRepository<>)).Use(typeof (Repository<>));
});
You could greate something like Repository base :
public class RepositoryBase<T> : IRepository<T> where T : Entity
then have something like this :
public class UserRepository : RepositoryBase<User>, IUserRepository
public class OtherRepository : RepositoryBase<Other>, IOtherRepository
where your repositories interfaces impelement the generic repository interface like that :
public interface IUserRepository : IRepository<User>
public interface IOtherRepository : IRepository<Other>
and then you could register it like that :
For(typeof (IRepository<>)).Use(typeof (RepositoryBase<>));
It works for me.
Here's a workaround, as we couldn't find any shorter way of making that mapping.
First, map to an open generic implementation class, as discussed elsewhere:
For(typeof(IRepository<>)).Use(typeof(ConcreteRepository<>));
Then, for each repository with custom behavior, add extension methods on the appropriate interface. For instance, supposing your MailoutStatusRepository has a method GetStatus(), you might translate that to an extension method on IRepository<MailoutStatusRepository>:
public static Status GetStatus(this IRepository<MailoutStatusRepository> repo,
Mailout mail)
{
return mail.Status; // or whatever
}
Now you have the custom repository behavior without having to worry about casting StructureMap's output to some custom class:
var repo = container.GetInstance<IRepository<MailoutStatusRepository>>();
var status = repo.GetStatus(mailout);
Another benefit of this approach is that your custom repository behavior works regardless of your repository implementation: in tests and in production code. The only downside (I think) is that your repositories are necessarily stateless, but we haven't found this to be a problem at all.
Scan(x =>
{
x.WithDefaultConventions();
x.AssemblyContainingType(typeof(UserRepository));
x.AddAllTypesOf(typeof(Repository<>));
x.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
});
WithDefaultConventions is the important part of the shown code, because with this setting you say StructureMap to use the convention of mappping IUserRepository to UserRepository . So StructureMap proceed from the assumption that the class is named like the name of the interface without the prefix I.
High Level
With StructureMap, Can I define a assembly scan rule that for an interface IRequestService<T> will return the object named TRequestService
Examples:
FooRequestService is injected when IRequestService<FooRequest> is requested
BarRequestService is injected when IRequestService<BarRequest> is requested
Details
I have a generic interface defined
public interface IRequestService<T> where T : Request
{
Response TransformRequest(T request, User current);
}
and then I have multiple Request objects that implement this interface
public class FooRequestService : IRequestService<Foo>
{
public Response TransformRequest(Foo request, User current) { ... }
}
public class BarRequestService : IRequestService<Bar>
{
public Response TransformRequest(Bar request, User current) { ... }
}
Now I am at the point where I need to register these classes so that StructureMap knows how to create them because in my controller I want have the following ctor (which I want StructureMap to inject a FooRequestService into)
public MyController(IRequestService<Foo> fooRequestService) { ... }
Right now to get around my issue I have implemented an empty interface and instead of having the FooRequestService implement the generic interface I have it implement this empty interface
public interface IFooRequestService : IRequestService<Foo> { }
Then my controllers ctor looks like so, which works with StructureMaps' Default Convention Scanner
public MyController(IFooRequestService fooRequestService) { ... }
How could I create a rule with StructureMap's assembly scanner to register all objects named TRequestService with IRequestService<T> (where T = "Foo", "Bar", etc) so that I don't have to create these empty Interface definitions?
To throw something else into the mix, where I am handling StructureMap's assembly scanning does not have any reference to the assembly that defines IRequestService<T> so this has to use some sort of reflection when doing this. I scanned the answer to "StructureMap Auto registration for generic types using Scan" but it seems as though that answer requires a reference to the assembly that contains the interface definition.
I am on the path of trying to write a custom StructureMap.Graph.ITypeScanner but I am kind of stuck on what to do there (mainly because I have little experience with reflection).
You are on the right path with the scanner. Thankfully there is one built into StructureMap. Unfortunately it is not yet, as of this writing, released. Get the latest from trunk and you will see a few new things available within the scanner configuration. An example for your needs is below.
public class MyRegistry : Registry
{
public MyRegistry()
{
Scan(x =>
{
x.TheCallingAssembly();
//x.AssembliesFromApplicationBaseDirectory();
x.WithDefaultConventions();
x.ConnectImplementationsToTypesClosing(typeof (IRequestService<>));
});
}
}
First you need to tell the scanner configuration which assemblies to include in the scan. The commented AssembliesFromApplicationBaseDirectory() method also might help if you are not doing a registry per assembly.
To get your generic types into the container use ConnectImplementationsToTypesClosing.
For an example on how to setup use registries when setting up the container see:
http://structuremap.sourceforge.net/ConfiguringStructureMap.htm
If you like you can skip using registries in general and just do a scan within ObjectFactory.Initialize.
Hope this helps.
I have a class that takes an array of interfaces in the constructor:
public class Foo<T1, T2> : IFoo<T1, T2>
{
public Foo(IBar[] bars)
{
...
}
}
My container registration looks as follows:
container.Register(AllTypes.Pick().FromAssemblyNamed("...")
.WithService.FirstInterface());
container.AddComponent("foo", typeof(IFoo<,>), typeof(Foo<,>));
I have several implementations of IBar, and the container can definately locate them, as calling ServiceLocator.Current.GetAllInstances<IBar>() works fine.
However, if I try to get an instance of IFoo, it throws an exception saying it couldn't satisfy the deoendency... "which was not registered".
If I change the constructor to take a single instance of IBar it works fine.
Any ideas?
Add the ArrayResolver:
container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel));