Is there a way to explicitly register open generic decorators with castle windsor - castle-windsor

I use castle windsor a lot in a project i'm working on and use decorators a little so I might have something like this in my installer
Component.For<IMyViewModelService>().ImplementedBy<MyViewModelServiceCacheDecorator>().LifestyleTransient()
Component.For<IMyViewModelService>().ImplementedBy<MyViewModelService>().LifestyleTransient()
So doing this is easy enough and works well. I started reading around the simple injector framework and I really like they way you can specifically set the decorators on open generics when using the command pattern.
https://simpleinjector.readthedocs.org/en/latest/advanced.html#decorators
Does castle windsor have any functionality that allows you to do the same thing in this declarative manner? I'm using castle windsor 3.3 and always stay with the latest.
I see this question which is kind of similar but doesn't have a full outcome
registering open generic decorators for typed implementations in castle windsor

Perhaps I'm not understanding what you're trying to do, but Castle supports open generic decorators just fine. Given these objects:
public interface IService<T>
{
void Info();
}
public class Service<T> : IService<T>
{
public void Info()
{
Console.WriteLine(GetType());
}
}
public class ServiceDecorator<T> : IService<T>
{
readonly IService<T> service;
public ServiceDecorator(IService<T> service)
{
this.service = service;
}
public void Info()
{
Console.WriteLine(GetType());
service.Info();
}
}
And this registration and resolution:
container.Register(Component.For(typeof(IService<>)).ImplementedBy(typeof(ServiceDecorator<>)));
container.Register(Component.For(typeof(IService<>)).ImplementedBy(typeof(Service<>)));
Then resolving the service and calling Info:
IService<int> service = container.Resolve<IService<int>>();
service.Info();
Will print:
Sample.ServiceDecorator`1[System.Int32]
Sample.Service`1[System.Int32]
If this is not what you're trying to do, please update your question with a more precise example.

Related

Register interfaces with no concrete implementations to return a generated type/proxy

I want to auto register all interfaces which name ends with "Service" and also doesn't have concrete implementations to be resolved to a generated type/proxy (which off course differs per interface).
So when I want to resolve IContractService I want it to return a proxied object. I got this idea from this article where they implemented it in some way with Castle Windsor.
What would be the structuremap approach for achieving this. I tried all kind of things with custom conventions and all but I can't get my head around it.
I fixed this by using Castle's Dynamic Proxy and a StructureMap convention. BTW. I also renamed some of the classes mentioned in the article.
public class InfraRegistry : Registry
{
public InfraRegistry()
{
For<IClientProviderFactory>().Use<WcfClientProviderProviderFactory>();
Scan(scan =>
{
scan.AssemblyContainingType<MidleWareServiceConvention>();
scan.Convention<MidleWareServiceConvention>();
});
}
}
public class MidleWareServiceConvention : IRegistrationConvention
{
private readonly ProxyGenerator _proxyGen = new ProxyGenerator();
public void Process(Type type, Registry registry)
{
if (type.IsInterface && type.Name.EndsWith("Service", StringComparison.OrdinalIgnoreCase))
{
registry.For(type)
.HybridHttpOrThreadLocalScoped()
.Use(
context =>
_proxyGen.CreateInterfaceProxyWithoutTarget(type,
new WcfInterceptor(
context.GetInstance<IClientProviderFactory>())));
}
}
}

Intercepting the concrete implementation (as opposed to service) using Castle Windsor

I'm experimenting with interception in Castle Windsor and notice that interceptors seem to be created as decorators of my service interface.
In other words, if I have an interface "ISomethingDoer" and a concrete "ConcreteSomethingDoer", the proxy implements ISomethingDoer but does not inherit from ConcreteSomethingDoer.
This is fine, and no doubt by design, but what I'm wondering is whether I can intercept protected virtual methods in my concrete classes that wouldn't be known by the public interface. I am doing this in order to add logging support, but I might want to log some of the specific internal details of a class.
In my slightly unimaginative test case I have this:
public interface ISomethingDoer
{
void DoSomething(int Count);
}
[Loggable]
public class ConcreteSomethingDoer : ISomethingDoer
{
public void DoSomething(int Count)
{
for (var A = 0; A < Count; A++)
{
DoThisThing(A);
}
}
[Loggable]
protected virtual void DoThisThing(int A)
{
("Doing a thing with " + A.ToString()).Dump();
}
}
So what I want to do is log calls to "DoThisThing" even though it's not part of the interface.
I've managed to get this working in Autofac. (I've created a Linqpad script here: http://share.linqpad.net/frn5a2.linq) but am struggling with Castle Windsor (see http://share.linqpad.net/wn7877.linq)
In both cases my interceptor is the same and looks like this:
public class Logger : IInterceptor
{
public void Intercept(IInvocation Invocation)
{
String.Format("Calling method {0} on type {1} with parameters {2}",
Invocation.Method.Name,
Invocation.InvocationTarget.GetType().Name,
String.Join(", ", Invocation.Arguments.Select(a => (a ?? "*null*").ToString()).ToArray())).Dump();
Invocation.Proceed();
"Done".Dump();
}
}
What I really want to do is say "any classes with a [Loggable] attribute, should use the logging interceptor". In the Autofac example I've specifically attached a logger to the registration, whereas with Castle I'm using an IModelInterceptorsSelector which looks like this:
public class LoggerInterceptorSelector : IModelInterceptorsSelector
{
public bool HasInterceptors(ComponentModel Model)
{
return Model.Implementation.IsDefined(typeof(LoggableAttribute), true);
}
public InterceptorReference[] SelectInterceptors(ComponentModel Model, InterceptorReference[] Interceptors)
{
return new[]
{
InterceptorReference.ForType<Logger>()
};
}
}
Finally, the code to execute all this is:
var Container = new WindsorContainer();
Container.Register(
Component.For<Logger>().LifeStyle.Transient
);
Container.Kernel.ProxyFactory.AddInterceptorSelector(new LoggerInterceptorSelector());
Container.Register(
Component.For<ISomethingDoer>()
.ImplementedBy<ConcreteSomethingDoer>()
.LifeStyle.Transient
);
var Doer = Container.Resolve<ISomethingDoer>();
Doer.DoSomething(5);
When run I would expect to see "Calling method DoThisThing with parameters x" for each time the method is called. Instead I only get the call to DoSomething logged.
I can see why Castle Windsor is doing this, but I'm wondering if there is a way to tweak the behaviour?
(As a side-note I don't want to use Windsor's own interceptor attributes as I don't want to introduce dependencies to Castle outside of my composition root.)
I have tried resolving the ConcreteSomethingDoer specifically and this works, but not if I'm resolving the ISomethingDoer.
Apologies for the long post, and also apologies because I am pretty new to Castle Windsor!
I you could register like:
Container.Register(
Component.For<ISomethingDoer, ConcreteSomethingDoer>()
.ImplementedBy<ConcreteSomethingDoer>()
.LifeStyle.Transient
);
This should create a class proxy by deriving from ConcreteSomethingDoer. However this won't work with dynamic interceptors. However you probably can work around that by creating a facility which registers the interceptor when needed.

Launching a JUnit test from an eclipse plugin using a custom JUnit runner implementation

I have written a custom JUnit runner that I want to become part of an eclipse plugin that will launch tests using this runner without having to apply the #RunWith annotation to the class. I have managed to get an additional item under the 'Run As' context menu, using the org.eclipse.debug.ui.launchShortcuts extension point. However, I am not sure how to invoke the test using my custom runner.
So I figured out a way to do what I wanted. However, it does seem a bit hacky. But, I thought that I would post the answer here in case someone else runs into the same problem.
First you have to register a junit kind like this:
<extension point="org.eclipse.jdt.junit.internal_testKinds">
<kind
id="my.junit.kind"
displayName="Your Kind Name"
finderClass="org.eclipse.jdt.internal.junit.launcher.JUnit4TestFinder"
loaderPluginId="org.eclipse.jdt.junit4.runtime"
loaderClass="your.test.loader.MyLoaderClass">
<runtimeClasspathEntry pluginId="org.eclipse.jdt.junit4.runtime" />
<runtimeClasspathEntry pluginId="org.eclipse.jdt.junit.core" />
<runtimeClasspathEntry pluginId="org.eclipse.jdt.junit.runtime"/>
</kind>
</extension>
In the xml you have to specify a custom implementation of org.eclipse.jdt.internal.junit.runner.ITestLoaderwhich in turn returns an implementation of org.eclipse.jdt.internal.junit.runner.ITestReference. The core part is the implementation of ITestReference, because this is where you create an instance of your custom JUnit runner.
public class MyTestReference extends JUnit4TestReference
{
public MyTestReference(final Class<?> p_clazz, String[] p_failureNames)
{
super(new Request()
{
#Override
public Runner getRunner()
{
return new MyCustomRunner(p_clazz);
}
}, p_failureNames);
}
...
}
Then finally you have to link this with a launch shortcut that sets the kind appropriately
public class MyJunitLaunchShortcut extends JUnitLaunchShortcut
{
#Override
protected ILaunchConfigurationWorkingCopy createLaunchConfiguration(IJavaElement p_element) throws CoreException
{
ILaunchConfigurationWorkingCopy config = super.createLaunchConfiguration(p_element);
config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND, "my.junit.kind");
return config;
}
}
This does use a bunch of internal classes, so there is probably a better way. But this seems to work.

Basic Windsor Constructor Injection

I am new to Windsor and am trying to implement the most basic constructor injection. Apparently the API has changed so much over the recent versions that the documentation that is for the current version seems to assume you already know how to do it, and the documentation for the old versions is outdated.
I have a simple test component:
public class ConstructorInjectedComponent
{
public IMyComponent Component { get; set; }
public ConstructorInjectedComponent(IMyComponent component)
{
Component = component;
}
}
There is a simple implementation of IMyComponent:
public class AMyComponent : IMyComponent
{
public string Name { get; set; }
public AMyComponent()
{
Name = Guid.NewGuid().ToString("N");
}
}
And I want to somehow register my types with Windsor such that I can get back an instance of ConstructorInjectedComponent that contains an instance of its dependency: IMyComponent.
I've register AMyComponent like so:
_container.Register(Component.For(typeof(AMyComponent)));
I've register ConstructorInjectedComponent like this:
_container.Register(Component.For(typeof(ConstructorInjectedComponent)));
and tried to resolve it with
_container.Resolve(typeof(ConstructorInjectedComponent));
But that fails with "can't create component ConstructorInjectedComponent because it has dependencies which need to be satisfied.
so I try to pass in an IDictionary of dependencies for the ConstructorInjectedComponent ... and this is where the documentation fails me.
I have no idea how to define that dictionary. I can find no documentation which explains it. I've tried this:
var d = new Dictionary<string, string>() {{"IMyComponent", "AMyComponent"}};
_container.Register(Component.For(typeof(ConstructorInjectedComponent))
.DependsOn(dependencies));
But that fails with the same "has dependencies that need to be resolved" error.
What am I doing wrong?
First it's crucial to make sure you understand the basic concepts, namely what a component is, what a service is, and what a dependency is.
The documentation about it is quite good.
The documentation about how to use registration API should help you get going.
The tl;dr asnwer is: since ConstructorInjectedComponent depends on IMyComponent make sure you register AMyComponent to expose IMyComponent as a service.
_container.Register(Component.For<IMyComponent>().ImplementedBy<AMyComponent>());

Does Spring Support JSON Configuration?

Does anyone know if Spring has any extensions that allow for configuring its ApplicationContext via JSON (or really any other format) rather than XML? I couldn't find anything in the official docs, but I was wondering if there were any other open source extensions that could allow this.
Just to be clear, I'm not talking about configuring SpringMVC to set up a RESTful JSON-based web service or anything like that, just if it's possible to do Spring app configuration via JSON instead of XML.
As far as I know there is no project to support JSON as configuration source. It should be relatively easy to kick-start, (Spring container has no dependency on XML, it is just a way to construct bean definitions). However it is much more work than you might think.
Note that Spring provides xml-schema to assist you in writing correct XML. You won't get that much in JSON. Also many DSLs were built on top of Spring XML and custom namespaces support (spring-integration, mule-esb and others use it).
If you hate XML (many do), try out Java Configuration, available since 3.0 and improved in 3.1:
#Configuration
public class MyBeans {
#Bean
public Foo foo() {
return new Foo();
}
#Bean
public Bar bar() {
return new Bar(foo());
}
#Bean
public Buzz buzz() {
Buzz buzz = new Buzz();
buzz.setFoo(foo());
return buzz;
}
}
Interesting fact: thanks to some fancy proxying, foo() is called exactly once here, even though referenced twice.
Try JSConf library available on maven central, it's support Properties, HOCON and JSON format.
You can inject values from external file to your service and more !
Sample usage of JavaConfig :
You data stored on file app.conf
{
"root":{
"simpleConf":{
"url":"Hello World",
"port":12,
"aMap":{
"key1":"value1",
"key2":"value2"
},
"aList":[
"value1",
"value2"
]
}}
You service where your configuration must be inject
#Service("service")
public class Service {
#Autowired
private ConfigBean configBean;
}
Declare a interface to access your configuration values from your service
#ConfigurationProperties("root/simpleConf")
public interface ConfigBean {
String getUrl();
int getPort();
Map getAMap();
List getAList();
}
And your Spring configuration bean :
#Configuration
public class ContextConfiguration {
#Bean
public static ConfigurationFactory configurationFactory() {
return new ConfigurationFactory().withResourceName("app.conf") //
.withScanPackage("org.jsconf.core.sample.bean");
}
}