I need to modify an existing web app to use Castle.Windsor as IOC container. It was originally developed with StructureMap.
I am stuck with the following problem.
Lets say I have registered a couple of interfaces and their corresponding implementations:
IFoo -> Foo
IBar -> Bar
Calling container.Resolve<IFoo>() or container.Resolve<IBar>() works just fine. This means that the services are registered correctly.
I have a Web Api class with dependencies on other services, such as IFoo
public class BadRequestErrorHandler : HttpErrorHandler
{
// services
public BadRequestErrorHandler(IFoo foo) {...} // has dependency on IFoo
}
In StructureMap I can call:
var test = ObjectFactory.GetInstance<BadRequestErrorHandler>();
this will resolve the IFoo dependency.
Now this does not work with windsor.
How can this be achieved with windsor?
Thanks!
* EDIT *
I was just able to make it work by explicitely registering the BadRequestErrorHandler.
container.Register(Component.For<BadRequestErrorHandler>());
I am just hoping there is a better way to achieve this, that does not involve registering classes that have dependencies. I have a bunch of them...
* EDIT 2 **
To ease the pain, I added a special method to deal with these concrete types.
public T GetInstanceWithAutoRegister<T>()
{
if (container.Kernel.GetHandler(typeof(T)) == null)
{
container.Register(Component.For<T>());
}
return container.Resolve<T>();
}
public object GetInstanceWithAutoRegister(Type pluginType)
{
if (container.Kernel.GetHandler(pluginType) == null)
{
container.Register(Component.For(pluginType));
}
return container.Resolve(pluginType);
}
not ideal, but at least better than having to explicetly register each type. Hope someone has a better solution
You can achieve what you want by registering an ILazyComponentLoader which is a hook that gets called by Windsor as a "last resort" when a component cannot be resolved.
In your case, the implementation would probably look somewhat like this:
public class JustLetWindsorResolveAllConcreteTypes : ILazyComponentLoader
{
public IRegistration Load(string key, Type service)
{
return Component.For(service);
}
}
-and then it should be registered as such:
container.Register(Component.For<ILazyComponentLoader>()
.ImplementedBy<JustLetWindsorResolveAllConcreteTypes>());
You can read more about it in the docs.
Related
With Autofac, what is the proper way to register types or declare dependencies for this type of circular graph?
public interface IComponent
{
void DoSomething();
}
public class AComponent: IComponent
{
...
}
public class BComponent: IComponent
{
...
}
public class CompositeComponent: IComponent
{
public CompositeComponent(IEnumerable<IComponent> components)
{
this.components = components;
}
public void DoSomething()
{
foreach(var component in components)
component.DoSomething();
}
}
The end goal would be that CompositeComponent be the default registration of IComponent and simply pass down calls to all other implementations.
I am gathering that the intent of the question is that you have some implementations of IComponent and you have some sort of CompositeComponent that also implements IComponent. CompositeComponent needs all of the registered IComponent instances except itself otherwise it creates a circular dependency.
This whole thing overlaps pretty heavily with one of our FAQs: "How do I pick a service implementation by context?"
You have some options. In order of my personal recommendation:
Option 1: Redesign the Interfaces
There are actually two concepts going on here - the notion of an individual handler and the notion of a thing that aggregates a set of individual handlers.
Using less generic terms, you might have an IMessageHandler interface and then something that passes a message through the set of all IMessageHandler implementations, but that thing that aggregates the handlers and deals with errors and ensuring the message is handled only by the right handler and all that... that isn't, itself, also a message handler. It's a message processor. So you'd actually have two different interfaces, even if the methods on the interface look the same - IMessageHandler and IMessageProcessor.
Back in your generic component terms, that'd mean you have IComponent like you do now, but you'd also add an IComponentManager interface. CompositeComponent would change to implement that.
public interface IComponentManager
{
void DoSomething();
}
public class ComponentManager : IComponentManager
{
public ComponentManager(IEnumerable<IComponent> components)
{
this.components = components;
}
public void DoSomething()
{
foreach(var component in components)
component.DoSomething();
}
}
Option 2: Use Keyed Services
If you won't (or can't) redesign, you can "flag" which registrations should contribute to the composite by using service keys. When you register the composite, don't use a key... but do specify that the parameter you want for the constructor should resolve from the keyed contributors.
builder.RegisterType<AComponent>()
.Keyed<IComponent>("contributor");
builder.RegisterType<BComponent>()
.Keyed<IComponent>("contributor");
builder.RegisterType<CompositeComponent>()
.As<IComponent>()
.WithParameter(
new ResolvedParameter(
(pi, ctx) => pi.Name == "components",
(pi, ctx) => ctx.ResolveKeyed<IEnumerable<IComponent>>("contributor")));
When you resolve IComponent without providing a key, you'll get the CompositeComponent since it's the only one that was registered that way.
Option 3: Use Lambdas
If you know up front the set of components that should go into the composite, you could just build that up in a lambda and not over-DI the whole thing.
builder.Register(ctx =>
{
var components = new IComponent[]
{
new AComponent(),
new BComponent()
};
return new CompositeComponent(components);
}).As<IComponent>();
It's more manual, but it's also very clear. You could resolve individual constructor parameters for AComponent and BComponent using the ctx lambda parameter if needed.
I have a Service that need inject more than one provider, see below for example. How to use Unity to implement this feature?
public class MyService: IMyService
{
public MyService(IEnumerable<Provider> Providers);
}
I know this is an old question, but maybe this will help someone else that stumbles upon this.
As long as you register the implementations with a specific name, this is possible to easily inject. You will then get all registered implementations.
public class MyService: IMyService
{
public MyService(IProvider[] providers)
{
// Do something with the providers
}
}
Just make sure to inject them as an array. Unity will understand this. And when you register them you can register them as such:
container.RegisterType<IProvider, FooProvider>("Foo");
container.RegisterType<IProvider, BarProvider>("Bar");
One way is to inject the UnityContainer itself, and then resolve all the Providers you need:
public class MyService : IMyService
{
public class MyService(IUnityContainer iocContainer)
{
var providers = iocContainer.ResolveAll<IProvider>();
}
}
The only thing you will need to do is register the UnityContainer with itself somewhere on setup:
unityContainer.Register<IUnityContainer>(unityContainer, new ContainerControllerLifetimeManager());
Im trying to use CDI extensions to discover JAX-RS resources at runtime and automatically publish them under different base URIs in a Java SE environment. Applications should not need to extend javax.ws.rs.core.Application themselves if possible.
I have read RestEasy documentation and javadoc but failed to find any obvious way to modify the #ApplicationPath at runtime.
One idea that im exploring is to try generate javax.ws.rs.core.Application and set the #ApplicationPath base URI programmatically, maybe by using an AnnotatedType CDI extension, and publish that as a * org.jboss.resteasy.spi.ResteasyDeployment`.
Are there other/better ways to do this?
EDIT:
Trying CDI extension event ProcessAnnotatedType to change #javax.ws.rs.Path of JAX-RS resources.
<X> void process(#Observes ProcessAnnotatedType<X> pat) {
if (!pat.getAnnotatedType().isAnnotationPresent(javax.ws.rs.Path.class)) {
return;
}
final AnnotatedType<X> org = pat.getAnnotatedType();
AnnotatedType<X> wrapped = new AnnotatedType<X>() {
#Override
public <T extends Annotation> T getAnnotation(final Class<T> annotation) {
if (javax.ws.rs.Path.class.equals(annotation)) {
class PathLiteral extends AnnotationLiteral<javax.ws.rs.Path> implements javax.ws.rs.Path {
#Override
public String value() {
return "change_me/" + (javax.ws.rs.Path) org.getAnnotation(annotation);
}
}
return (T) new PathLiteral();
} else {
return org.getAnnotation(annotation);
}
}
pat.setAnnotatedType(wrapped);
}
... then after bootstrap, constructing the bean using javax.enterprise.inject.spi.BeanManager was expecting the following code to print "change_me/...."
Set<Bean<?>> beans = beanManager.getBeans(jaxrsClass);
for (Bean<?> bean : beans) {
CreationalContext cc = bm.createCreationalContext(bean);
Object jaxrs = bean.create(cc);
Path p = jaxrs.getClass().getAnnotation(Path.class);
System.out.println(p.value());
}
... but this does not work. javax.ws.rs.Path is unchanged for JAX-RS resource 'jaxrsClass'.
What is wrong?
I doubt this can be done in a reliable way. It probably all comes down to which happens first: the CDI bootstrap or JAX-RS, of course in the future or in other application servers it could all be done in parallel.
It's certainly a cool idea though. What have they said on the RestEasy forums?
We are already using such an approach.
We are using the feature to use Subresource locators and take the power of guice.
At the startup we are scanning the classpath for all resources annotated with #Path. After that we are extracting the path and binding the resources with the help of Names/#Named. So the resources can later be injected with the help of the name.
bind(..).annotatedWith(Names.named("path")).to(..)
The next step is that you need a resource with a subresource locator.
#Path("{name}")
public Object find(#PathParam("name") name){
return injector.getInstance(..);
}
You could use this approach to bind them at runtime and also to change the original annotated path.
I am trying to test a repository that uses DbContext
The issue I am running into is that DbCOntext wants to return DbSet for certain types
I can't even mock IDbSet as it has a PRIVATE CTOR?!?!?!
How is everyone getting over this?
You need to make use of an adapter or wrapper. The DbContext is third party code. Your code should hide this behind an abstraction, remember this is just an implementation detail about how the internals of your system works. You should be free to change this at any time.
public class ThatsHardToTest
{
// Private constructors, slow start up time etc...
public int AlwaysReturnOneExceptInSuperRareScnearios()
{
// Complex logic.
return 1;
}
}
Now if we want to test our code when the above method goes wrong, e.g database system is offline. I don't want the test to hit the database, so we need an adapter around this third party code. I would either make an interface or base class.
public class MyTestAdapter : IExampleAdapter
{
public int ReturnWhateverIWant()
{
return -1;
}
}
I would use MyTestAdapter for unit testing my code, as I can control what it does. For the production code you simply substitute this with an adapter which delegates to the real production system. For example:
public class MyRealAdapter : IExampleAdapter
{
public int ReturnWhateverIWant()
{
return new ThatsHardToTest().AlwaysReturnOneExceptInSuperRareScnearios();
}
}
While creating classes using Generators, it's possible to discover all subclasses of a type. You can find this technique for example in the GWT Showcase source (see full code):
JClassType cwType = null;
try {
cwType = context.getTypeOracle().getType(ContentWidget.class.getName());
} catch (NotFoundException e) {
logger.log(TreeLogger.ERROR, "Cannot find ContentWidget class", e);
throw new UnableToCompleteException();
}
JClassType[] types = cwType.getSubtypes();
I would like to do something similar, but instead of extending a class (or implementing an interface)
public class SomeWidget extends ContentWidget { ... }
, could I also do this by annotating Widgets?
#MyAnnotation(...)
public class SomeWidget extends Widget { ... }
And then finding all Widgets that are annotated with #MyAnnotation? I couldn't find a method like JAnnotationType.getAnnotatedTypes(), but maybe I'm just blind?
Note: I was able to make it work with the Google Reflections library, using reflections.getTypesAnnotatedWith(SomeAnnotation.class), but I'd prefer using the GeneratorContext instead, especially because this works a lot better when reloading the app in DevMode.
Yes - easiest way is to iterate through all types, and check them for the annotation. You might have other rules too (is public, is non-abstract) that should also be done at that time.
for (JClassType type : oracle.getTypes()) {
MyAnnotation annotation = type.getAnnotation(MyAnnotation.class);
if (annotation != null && ...) {
// handle this type
}
}
The TypeOracle instance can be obtained from the GeneratorContext using context.getTypeOracle().
Note that this will only give you access to types on the source path. That is, only types currently available based on the modules being inherited and <source> tags in use.