Castle Windsor 2.5. This fails. Why? Is it designated beahvior or a bug? Seems sub dependency resolvers are not even queried when resolving top-level services.
class Program
{
class Resolver :ISubDependencyResolver
{
public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
return new Program();
}
public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
return dependency.TargetType == typeof (Program);
}
}
[STAThread]
static void Main()
{
var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new Resolver());
var xxx = container.Resolve<Program>();
}
}
These are sub dependency resolvers. They resolve dependencies, not root services. What are you really trying to do? Why not register the object upfront?
Related
I want to add some custom serialization logic so that the converted json contains camel case properties.
For that reason i tried to replace the default IJsonSerializer with one the i found in this link:
https://github.com/SignalR/SignalR/issues/500
However there seems to be a problem. More specifically, the JsonNetSerializer and IJsonSerializer classes do not exist in any of the signalR assemblies. Is there any change that happened to the recent version of signalR in that respect?
Just to clarify this a bit, as of SignalR 2 you can't replace the serializer with one that isn't from from JSON.NET. However, the JSON.NET serializer used by SinglR can be created and set using the DependacyResolver.
Here's an example where a new JsonSerializer is created to handle reference loops:
protected void Application_Start()
{
var serializerSettings = new JsonSerializerSettings();
serializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
serializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
var serializer = JsonSerializer.Create(serializerSettings);
GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => serializer);
}
In SignalR 2.0 you can't replace the JsonSerializer, there's no more IJsonSerializer abstraction. It's always JSON.NET.
Here's an example of overriding the SignalR Dependency Resolver using StructureMap.
In this particular example, I'm converting to camelCase properties and converting enums as strings.
During startup:
Microsoft.AspNet.SignalR.GlobalHost.DependencyResolver = new StructureMapSignalRDependencyResolver();
Here's the class:
public class StructureMapSignalRDependencyResolver : Microsoft.AspNet.SignalR.DefaultDependencyResolver
{
public override object GetService(Type serviceType)
{
object service;
if (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
{
// Concrete type resolution
service = StructureMap.ObjectFactory.GetInstance(serviceType);
}
else
{
// Other type resolution with base fallback
service = StructureMap.ObjectFactory.TryGetInstance(serviceType) ?? base.GetService(serviceType);
}
return service;
}
public override IEnumerable<object> GetServices(Type serviceType)
{
var objects = StructureMap.ObjectFactory.GetAllInstances(serviceType).Cast<object>();
return objects.Concat(base.GetServices(serviceType));
}
}
And StructureMap was setup with:
ObjectFactory.Configure(c =>
{
c.Scan(a =>
{
// scan the assembly that SignalR is referenced by
a.AssemblyContainingType<AppHost>();
a.WithDefaultConventions();
});
c.For<Newtonsoft.Json.JsonSerializer>()
.Singleton()
.Use(new Newtonsoft.Json.JsonSerializer
{
ContractResolver = new SignalRContractResolver(),
Converters = { new Newtonsoft.Json.Converters.StringEnumConverter() }
});
});
Here is the Contract Resolver:
public class SignalRContractResolver : Newtonsoft.Json.Serialization.IContractResolver
{
private readonly Assembly _assembly;
private readonly Newtonsoft.Json.Serialization.IContractResolver _camelCaseContractResolver;
private readonly Newtonsoft.Json.Serialization.IContractResolver _defaultContractSerializer;
public SignalRContractResolver()
{
_defaultContractSerializer = new Newtonsoft.Json.Serialization.DefaultContractResolver();
_camelCaseContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
_assembly = typeof(Connection).Assembly;
}
public Newtonsoft.Json.Serialization.JsonContract ResolveContract(Type type)
{
if (type.Assembly.Equals(_assembly))
{
return _defaultContractSerializer.ResolveContract(type);
}
return _camelCaseContractResolver.ResolveContract(type);
}
}
Maybe abstract typed factories are not an easy point to start with Windsor (2.5.3 if it matters) but I've got to do it anyway.
I'm trying to build a factory giving back processors depending on message type. So far i've scavenged from different places following code:
public class Complicato
{
public static void Do(string[] args)
{
IKernel kernel = new DefaultKernel();
IWindsorContainer container = new WindsorContainer();
kernel.AddFacility<TypedFactoryFacility>();
container.Install();
container.Register(
Component.For<HandlerSelector, ITypedFactoryComponentSelector>(),
AllTypes.FromThisAssembly().BasedOn(typeof(ITrier<>))
.WithService.Base().Configure(conf => conf.LifeStyle.Is(LifestyleType.Transient)),
Component.For<Factor>(),
Component.For<ITryFactory>().AsFactory(c => c.SelectedWith<HandlerSelector>()).LifeStyle.Singleton);
var factor = container.Resolve<Factor>();
var factory = container.Resolve<ITryFactory>();
}
}
public class HandlerSelector : DefaultTypedFactoryComponentSelector
{
protected override Type GetComponentType(MethodInfo method, object[] arguments)
{
return typeof(ITrier<>).MakeGenericType(arguments[0].GetType());
}
}
public class Factor
{
private ITryFactory factory;
public void Try(IWhat onto)
{
factory.GetTrier(onto).Try(onto);
}
}
public interface ITryFactory
{
ITrier<IWhat> GetTrier(IWhat onto);
void Release(object elem);
}
public interface IWhat { }
public interface ITrier<in TWhat> where TWhat : IWhat
{
void Try(TWhat input);
}
public class TrierYes : ITrier<WhatYes>
{
public void Try(WhatYes input) { Console.WriteLine("Yes? " + input.Aye()); }
}
public class TrierNo : ITrier<WhatNot>
{
public void Try(WhatNot input) { Console.WriteLine("No? " + input.Naa()); }
}
public class WhatYes : IWhat
{
public bool Aye() { return true; }
}
public class WhatNot : IWhat
{
public bool Naa() { return false; }
}
Main problem here is that id doesn't work. First I get Factor with factory of null and then as a consequence trying to resolve factory explicitely gives me ComponentActivator: could not proxy Factories.Complex.ITryFactory with inner message of The interceptor Castle.TypedFactory.Interceptor could not be resolved and "Keys (components with specific keys) - Castle.TypedFactory.Interceptor which was not registered" in container. I don't even know if the Handler selector works, it's not in question so far.
If I make ITrier not generic - it suddenly starts working but it's definitely not what I'm trying to achieve.
So do I make some silly beginners mistake in Windsor configuration or misunderstand the idea of typed factory?
For completeness sake, here's the exception message:
Castle.MicroKernel.ComponentActivator.ComponentActivatorException was unhandled
Message=ComponentActivator: could not proxy Factories.Complex.ITryFactory
Source=Castle.Windsor
StackTrace:
at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstance(CreationContext context, Object[] arguments, Type[] signature) in e:\OSS.Code\Castle.Windsor\src\Castle.Windsor\MicroKernel\ComponentActivator\DefaultComponentActivator.cs:line 166
InnerException: Castle.MicroKernel.Resolvers.DependencyResolverException
Message=The interceptor Castle.TypedFactory.Interceptor could not be resolved
Source=Castle.Windsor
StackTrace:
at Castle.Core.InterceptorReference.Castle.MicroKernel.IReference<Castle.DynamicProxy.IInterceptor>.Resolve(IKernel kernel, CreationContext context) in e:\OSS.Code\Castle.Windsor\src\Castle.Windsor\Core\InterceptorReference.cs:line 142
And the winner is
container.AddFacility<TypedFactoryFacility>(); // good code
instead of
kernel.AddFacility<TypedFactoryFacility>(); // bad code
Now I only have the issues of not injected factory and improper HandlerSelector.
NullReference was solved by introducing explicit initializing constructor to the Factor. I don't know why I thought it works without.
Final version of the handler interface is following:
public interface ITrier<out TWhat> where TWhat: IWhat
{
void Try(IWhat input);
}
To permit covariance. Not über-elegant as requires unnecessary cast and handlers loosen their typedness. But this is cruel reality. You're either co or contra-variant.
I'm using Windsor to manage IoC for my controllers in a WebAPI project. I've got a DependencyResolver working nicely to resolve controller dependencies, but now I'm looking to inject dependencies into a custom action filter I'm using to manage authentication.
I've looked into using a custom ActionInvoker but it's not clear from the interface that WebAPI is using how I would go about resolving property dependencies on the custom action filter attribute before it executes. Anyone have a good example of how to do this in the MVC 4 RC?
EDIT: I'm aware you can't do constructor injection on filters, because they're attributes and therefore instantiated by the .NET framework - but I'm hoping there's some point in the execution lifecycle that happens AFTER the filter is instantiated but BEFORE it gets executed, where I could run some custom code to enumerate across the filters' public properties and inject the necessary services.
Action filters are attributes. In .NET attribute the instantiation process is managed by the .NET runtime and you don't have control over it. So one possibility is to use Poor Man's Dependency Injection which I would personally advice you against.
Another possibility is to use a marker attribute:
public class MyActionFilterAttribute : Attribute
{
}
and then have the action filter using constructor injection:
public class MyActionFilter : ActionFilterAttribute
{
private readonly IFoo _foo;
public MyActionFilter(IFoo foo)
{
_foo = foo;
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ActionDescriptor.GetCustomAttributes<MyActionFilterAttribute>().Any())
{
// The action is decorated with the marker attribute =>
// do something with _foo
}
}
}
and then register it as a global action filter in Application_Start:
IFoo foo = ....
GlobalConfiguration.Configuration.Filters.Add(new MyActionFilter(foo));
I had the same problem, but decided to go for the ServiceLocator (DependencyResolver.GetService) for this, as its in the framework it seems to me to be a valid approach
public class RequiresSessionAttribute :
ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var sessionService =
(ISessionService) actionContext
.ControllerContext.Configuration.DependencyResolver
.GetService(typeof (ISessionService));
var sessionId = HttpUtility
.ParseQueryString(actionContext.Request.RequestUri.Query)
.Get("sessionId");
if (sessionId == null
|| !sessionService.IsValid(sessionId))
throw new SessionException();
base.OnActionExecuting(actionContext);
}
}
and here is a test for this attribute, bit of a pain but possible
public class requires_sessionId
{
[Fact]
void can_call_action_with_session_id()
{
var context = GetContext("http://example.com/?sessionId=blaa");
var sut = new RequiresSessionAttribute();
Assert.DoesNotThrow(
() => sut.OnActionExecuting(context));
}
[Fact]
void can_not_call_action_without_session_id()
{
var context = GetContext("http://example.com/");
var sut = new RequiresSessionAttribute();
Assert.Throws<SessionException>(
() => sut.OnActionExecuting(context));
}
HttpActionContext GetContext(string url)
{
var sessionServiceMock = new Mock<ISessionService>();
sessionServiceMock
.Setup(x => x.IsValid(It.IsAny<string>()))
.Returns(true);
var dependancyResolverMock = new Mock<IDependencyResolver>();
dependancyResolverMock
.Setup(x => x.GetService(It.IsAny<Type>()))
.Returns(sessionServiceMock.Object);
var config = new HttpConfiguration
{
DependencyResolver = dependancyResolverMock.Object
};
var controllerContext = new HttpControllerContext
{
Configuration = config,
Request = new HttpRequestMessage(
HttpMethod.Get,
url)
};
return
new HttpActionContext
{
ControllerContext = controllerContext,
};
}
}
I am having trouble getting Castle Dynamic Proxy to intercept methods that are explicit interface implementations. I read here http://kozmic.pl/category/dynamicproxy/ that it should be possible to do this.
Here are my classes;
internal interface IDomainInterface
{
string DomainMethod();
}
public class DomainClass : IDomainInterface
{
string IDomainInterface.DomainMethod()
{
return "not intercepted";
}
}
Here is my interceptor class;
public class DomainClassInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (invocation.Method.Name == "DomainMethod")
invocation.ReturnValue = "intercepted";
else
invocation.Proceed();
}
}
And here is my test (which fails);
[TestClass]
public void can_intercept_explicit_interface_implementation()
{
// Create proxy
var generator = new ProxyGenerator();
var interceptor = new DomainClassInterceptor();
var proxy = (IDomainInterface)generator.CreateClassProxy(typeof(DomainClass), interceptor);
// Invoke proxy method
var result = proxy.DomainMethod();
// Check method was intercepted -- fails
Assert.AreEqual("intercepted", result);
}
In addition to not being able to intercept the explicit interface implementation, it also seems that I am not receiving a notification of a non-proxyable member.
Here is my proxy generation hook (which acts as a spy);
public class DomainClassProxyGenerationHook : IProxyGenerationHook
{
public int NonProxyableCount;
public void MethodsInspected() {}
public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo)
{
NonProxyableCount++;
}
public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
{
return true;
}
}
Here is my test (which again fails);
[TestMethod]
public void receive_notification_of_nonproxyable_explicit_interface_implementation()
{
// Create proxy with generation hook
var hook = new DomainClassProxyGenerationHook();
var options = new ProxyGenerationOptions(hook);
var generator = new ProxyGenerator();
var interceptor = new DomainClassInterceptor();
var proxy = (IDomainInterface)generator.CreateClassProxy(typeof(DomainClass), options, interceptor);
// Check that non-proxyable member notification was received -- fails
Assert.IsTrue(hook.NonProxyableCount > 0);
}
Has anyone had success in getting DP to intercept explicit interface implementations? If so, how?
You are creating a class proxy. Class proxy only intercepts virtual methods on the class, and an explicit implementation of an interface method in C# by definition is not virtual (since it's private).
If you want to intercept methods on the interface you need to explicitly tell DynamicProxy about it
var proxy = (IDomainInterface)generator.CreateClassProxy(typeof(DomainClass), new Type[] { typeof(IDomainInterface) }, interceptor);
Also your interface is marked as internal so made sure it's public for DynamicProxy (either make the interface public or add InternalsVisibleToAttribute).
With that your first test will pass, and the method will be intercepted.
My colleague set up a Windsor TypedFactoryFacility in our project.
I'm new to Windsor and don't understand how it is implementing the the methods in the IServiceFactory interface we register as a factory. When I saw a Create method that takes a type parameter T and returns a T, I figured that it's probably calling the container's Resolve method under the covers.
I need an overload of Create that takes a Type as a parameter and returns an object. Since the container's Resolve method has both of these flavors:
T Resolve<T>(string key);
object Resolve(Type service);
I thought adding the overload of Create would work. Instead, it appears to be trying to resolve a System.Object instead of the Type I pass in.
Is there a way to make Windsor implement my Create method the way I want it to? I've poked around a bit with reflector, but can't figure it out.
Here is the registration:
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<IServiceFactory>()
.AsFactory()
.LifeStyle.Transient);
and the interface itself:
public interface IServiceFactory
{
//Original Create method that works
T Create<T>();
//The overload that I need that throws an exception
object Create(Type service)
void Release(object service);
}
Do you want to call something like serviceFactory.Create(typeof(IMyServce)) instead of serviceFactory.Create<IMyService>()?
Try using reflection in an extension method, like this
public static class ServiceFactoryExtensions
{
public static object Create(this IServiceFactory factory, Type serviceType)
{
return typeof(IServiceFactory).GetMethod("Create")
.MakeGenericMethod(serviceType).Invoke(factory, new object[]{});
}
}
EDIT:
This extension method does indeed work with a factory created by Castle Windsor.
Here's my original test code, which you can drop into Program.cs of a VS2010 console application, add a reference to Castle.Core and Castle.Windsor, and run. I used Castle.Windsor 2.5.4.
using System;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
namespace StackOverflow9198461
{
public static class ServiceFactoryExtensions
{
public static object Create(this IServiceFactory factory, Type serviceType)
{
return typeof(IServiceFactory).GetMethod("Create")
.MakeGenericMethod(serviceType)
.Invoke(factory, new object[] { });
}
}
class Program
{
static void Main()
{
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component
.For<IServiceFactory>()
.AsFactory());
container.Register(Component
.For<IMyService>()
.ImplementedBy<MyService>()
.LifeStyle.Singleton);
var factory = container.Resolve<IServiceFactory>();
var s1 = factory.Create<IMyService>();
var s2 = factory.Create(typeof(IMyService));
Console.WriteLine(s1.GetType().FullName);
Console.WriteLine(s2.GetType().FullName);
if (s1 == s2) Console.WriteLine("Success");
}
}
public interface IServiceFactory
{
//Original Create method that works
T Create<T>();
////The overload that I need that throws an exception
//object Create(Type service)
void Release(object service);
}
public class MyService : IMyService
{
}
public interface IMyService
{
}
}