We are defining implementations to our services in an external xml configuration file. We have the name of the service, the class to instantiate, the assembly containing the class. We are migrating from an Spring AOP code.
For simple services it works without an itch with kernel.Bind().To().
We load the assembly, create an instance, return it to To().
However some services inherit from another class like :
internal abstract Bar<T>: EntityBo<T> where T : IAddress
{
protected Bar(IAddress adr)
{
}
}
internal Foo:Bar<ILocalAddress>, ILocalAddressService {
}
When I try to get ILocalAddressService from the Kernel, I get a Ninject.ActivationException :
Error activating ILocalAddress No matching bindings are available, and
the type is not self-bindable.
Activation path:
2) Injection of dependency ILocalAddress into parameter adr of constructor of type Foo
1) Request for ILocalAddressService
The Kernel is in a different project and doesn't know about the interface or its implementation.
How can I make it work ?
Related
I have registered following types with IOC (func) in App host.Classes & interfaces given below are in a separate class library .This class library contains a WCF service reference .
private void RegisteTyeps(Container container)
{
//Register Mapper
container.Register<IMapper>(c => _mapperConfiguration.CreateMapper());
container.RegisterAutoWiredAs<AppointmentHandler, IAppointmentHandler>().ReusedWithin(ReuseScope.Container);
container.RegisterAutoWiredAs<CalendarHandler, ICalendarHandler>().ReusedWithin(ReuseScope.Container);
container.RegisterAutoWiredAs<SettingHandler, ISettingHandler>().ReusedWithin(ReuseScope.Container);
}
I wanted to add some more service references (Which are slightly different than each other ) and generate proxies.Thus i added some more class libraries with respective service references .Each class libraries contains "same" interface and classe as mentioned above .
I wanted to dynamically load /Switch class library based on request header or something so that i can only use particular library which has the appropriate service reference & proxies.
How can i achieve this with service stack .Any one have any idea?
You can only register a dependency against a single Type or Interface in Funq. If you want to perform multiple registrations you would either need to register a Factory type, e.g:
container.Register(c => new AppointmentHandlers(
new AppointmentHandler1(),
new AppointmentHandler2());
Then resolve it with:
public AppointmentHandlers AppointmentHandlers { get; set; }
public object Any(MyRequest request)
{
var dep = AppointmentHandlers.AppointmentHandler1();
}
Otherwise you need to register them with different interfaces or use a named registration.
I'm trying to register multiple implementation of single interface, but I would like to avoid using named type registration. Let's say I'm having following code:
public interface IStorage { ... }
public class DocumentStorage : IStorage { ... }
public class ImageStorage : IStorage { ... }
public interface IRepository { ... }
public class DocumentRepository : IRepository
{
public DocumentRepository(IStorage storage /*, ... and other dependencies */) { ... }
}
And doing all Unity IoC registration on single file. Rest of application does not have access to container (+ service locator pattern is big no no in my code)
Registering this would then look like this:
container.RegisterType<IStorage, DocumentStorage>("document");
container.RegisterType<IStorage, ImageStorage>("image");
container.RegisterType<IRepository, DocumentRepository>(
new InjectionFactory((c, t, s) => new DocumentRepository(
c.Resolve<IStorage>("document") /*, ... resolve other deps here */)));
And here is lying my laziness issue - I really don't want to write resolution of all dependencies this way - this makes IoC hassle. I would have to go trough all registrations depending on one of IStorage implementations and resolve all other dependencies manually.
I was thinking of turned-around solution by registering DocumentStorage resolved by DocumentRepository - which I'm not able to figure out, and moreover, it is putting dependency on another side of "equation" ("register type for being injected to another type" (instead of "register type and let it be resolved if something depends on it")).
Is there any other way how to make registration easier? (I'm not focusing on factory here - I could imagine other non-factory-able usages requiring similar way of registering dependencies)
Thanks for any advice :)
I have ASP.NET Web Application and added dll to the project.
I glue it I chose Ninject Ioc.
Because Web Application must have default constructor I decided to glue it in following way:
public IPlayerDb PlayerDb { get; set; }
public Logon()
{
Global.Kernel.Inject(this);
}
IPlayerDb is in external DLL library 'Contracts.dll'
PlayerDb class implemented IPlayerDb is in other dll : 'DataAccess.dll'
In DataAccess.dll there is class making glueing :
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IDbConfig>().To<DbConfig>();
Bind<IPlayerDb>().To<PlayerDb>();
}
}
It's OK when I use my project after Visual Studio restarts (and IIS express I guess also).
But if I start to debug the application again it makes me following Error Message:
Error activating IPlayerDb
No matching bindings are available, and the type is not self-bindable.
Activation path:
2) Injection of dependency IPlayerDb into property PlayerDb of type Logon
1) Request for logon_aspx
An exception of type 'Ninject.ActivationException' occurred in Ninject.dll but was not handled in user code
So, what's wrong with it. Seems I did everything by manual. Advice needed.
I have a host application which provides a plugin interface that can be implemented by plugins. When initializing plugins the host app passes in the Structuremap registry so the plugin can register things
public interface IAppPlugin
{
void Initialize(IRegistry configure);
}
public class CatPlugin : IAppPlugin
{
public void Initialize(IRegistry configure)
{
configure.For<IFilter<IPet>>()
.Add<CatFilter<IPet>>();
}
}
In my host app I have an implementation of IPet, FeralCat and I want to get from structuremap any filters
ObjectFactory.TryGetInstance<IFilter<FeralCat>>
I was hoping this would return me the CatFilter filter registered by my plugin, but it doesnt (which makes sense really, I havent registered a matching type)
My plugin doesnt know about the FeralCat, how can I configure structuremap to return the CatFilter ?
You should take a look at Advanced StructureMap: connecting implementations to open generic types, it might be useful in your case.
But for your specific code:
var container = new Container();
container.Configure(
x =>
{
x.For(typeof(IPet)).Use(typeof(FeralCat));
x.For(typeof(IFilter<>)).Use(typeof(CatFilter<>));
});
var instances = container.GetAllInstances<IFilter<FeralCat>>();
Will give you an instance of CatFilter<FerelCat>.
I'd like to use NServiceBus profiles to override the concrete classes used in the Spring.net dependency injection for use in Integration Testing.
In my EndpointConfig class, I have a component being configured:
NServiceBus.Configure.Instance.Configurer.ConfigureComponent<RealCommunicator>(ComponentCallModelEnum.None);
(This bit is OK!)
I created a new profile:
public class StubThirdPartyProfile : NServiceBus.IProfile
{
}
And a behaviour class to implement it:
public class StubThirdPartyBehaviour : IHandleProfile<StubThirdPartyProfile>
{
public void ProfileActivated()
{
Configure.Instance.Configurer.ConfigureComponent<StubCommunicator>(ComponentCallModelEnum.None);
}
}
Both StubCommunicator and RealCommunicator implement the same interface and I was hoping that the profile would remove the old dependency and use the StubCommunicator instead but this is not the case. Is there a way to do this?
When the solution is run, I get the following error:
Spring.Objects.Factory.UnsatisfiedDependencyException:
Error creating object with name 'Namespace.CommandHandler' :
Unsatisfied dependency expressed through object property 'Communicator':
There are 2 objects of Type [Namespace.ICommunicator] for autowire by type,
when there should have been just 1 to be able to autowire property 'Communicator' of object
We're using the Spring.net framework in NServicebus configured as so:
Configure.With().SpringFrameworkBuilder()
.XmlSerializer().Log4Net()
.MsmqTransport()
.IsTransactional(true);
Instead of configuring the real component in the endpoint config class, consider registering it in a class which handles the other NServiceBus profiles - Lite, Integration, Production.