Trying to find the real cause of this and not having much fun!
Type is not resolved for member 'Castle.MicroKernel.Lifestyle.Scoped.CallContextLifetimeScope+SerializationReference,Castle.Windsor, Version=3.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc'.
This looks like a bug considering I have nothing register with the container using this lifestyle.
Faced same issue while doing MSTest. Adding Castle.Windsor.dll to GAC worked for me.
gacutil.exe /if "C:\Castle.Windsor.3.1.0\lib\net40\Castle.Windsor.dll"
I'm not sure what you are trying to do, but if your goal is implementing an IDependencyResolver (which looks like it since you are using scopes):
If you are implementing an IDependencyResolver, don't try to be clever and inherit from your IDependencyScope implementation. Create the Resolver from scratch. This is how I implemented my dependency resolver (which works):
public class WindsorDependencyResolver : IDependencyResolver {
private readonly IWindsorContainer _container;
public WindsorDependencyResolver(IWindsorContainer container)
{
_container = container;
}
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(_container);
}
public object GetService(Type serviceType)
{
return _container.Kernel.HasComponent(serviceType)
? _container.Resolve(serviceType)
: null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _container.ResolveAll(serviceType).Cast<object>();
}
public void Dispose()
{
}
}
public class WindsorDependencyScope : IDependencyScope {
private readonly IWindsorContainer _container;
private readonly IDisposable _scope;
private bool _disposed;
public WindsorDependencyScope(IWindsorContainer container)
{
_container = container;
_scope = _container.BeginScope();
}
public object GetService(Type serviceType)
{
EnsureNotDisposed();
return _container.Kernel.HasComponent(serviceType)
? _container.Kernel.Resolve(serviceType)
: null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
EnsureNotDisposed();
return _container.ResolveAll(serviceType).Cast<object>();
}
public void Dispose()
{
if(_disposed) return;
_scope.Dispose();
_disposed = true;
GC.SuppressFinalize(this);
}
private void EnsureNotDisposed()
{
if(_disposed) throw new ObjectDisposedException("WindsorDependencyScope");
}
}
And this was my first attempt (which produced your error):
public class WindsorDependencyResolver : WindsorDependencyScope, IDependencyResolver {
private readonly IWindsorContainer _container;
public WindsorDependencyResolver(IWindsorContainer container)
: base(container)
{
_container = container;
}
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(_container);
}
}
Related
This is my code:
public interface IUnitOfWork : IDisposable
{
IRepository<TEntity> GetRepository<TEntity>() where TEntity : class;
void Save();
}
public class UnitOfWork<TContext> : IUnitOfWork where TContext : IDbContext, new()
{
private readonly IDbContext _ctx;
private readonly Dictionary<Type, object> _repositories;
private bool _disposed;
...................
EmployeeService.cs
public class EmployeeService : EntityService<Employee>, IEmployeeService
{
readonly IUnitOfWork _unitOfWork;
readonly IRepository<Employee> _repository;
........
in console app when I call:
var employeeService = Injector.Instance.Resolve<IEmployeeService>();
I am getting below error message:
An unhandled exception of type 'Castle.MicroKernel.Handlers.GenericHandlerTypeMismatchException' occurred in Castle.Windsor.dll
Additional information: Types EfContext.DAL.IDbContext don't satisfy generic constraints of implementation type EfContext.DAL.UnitOfWork1 of component 'EfContext.DAL.UnitOfWork1'.this is likely a bug in the IGenericImplementationMatchingStrategy used (EfContext.DependencyInjection.UseStringGenericStrategy)
public class ConsoleAppInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
{
container.Register(Component.For(typeof(IUnitOfWork)).ImplementedBy(typeof(UnitOfWork<>), new UseStringGenericStrategy()).LifestyleTransient());
}
}
public class UseStringGenericStrategy : IGenericImplementationMatchingStrategy
{
public Type[] GetGenericArguments(ComponentModel model, CreationContext context)
{
if (context.RequestedType == typeof(IUnitOfWork))
{
var res = new[] { typeof(object) };
return res;
}
return null;
}
}
I have fixed my issue with changing the register line to:
// register
container.Register(Component.For(typeof(IUnitOfWork)).ImplementedBy(typeof(UnitOfWork<MyDbContext>),
new UseTypeGenericStrategy()).LifestyleTransient());
I am having some problem resolving ITcpServer when using TypedFactoryFacility. It seems that Windsor does not find a suitable component to be returned from factory for the interface. What is specific to my case is that the interface ITcpServer is non-generic while classes implementing it are both generic.
The following code throws when run:
Unhandled Exception: Castle.MicroKernel.ComponentNotFoundException: No
component for supporting the service
ConsoleApplication1.StandardTcpServer`1 was found at
Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type
service, IDictionary arguments, IReleasePolicy policy) at
Castle.Facilities.TypedFactory.TypedFactoryComponentResolver.Resolve(IKernelInternal
kernel, IReleasePolicy scope) at
Castle.Facilities.TypedFactory.Internal.TypedFactoryInterceptor.Resolve(IInvocation
invocation) at
Castle.Facilities.TypedFactory.Internal.TypedFactoryInterceptor.Intercept(IInvocation
invocation) at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.ITcpServerFactoryProxy.Create[T](String serverType,
T something)
The code:
class Program
{
static void Main(string[] args)
{
IWindsorContainer container = new WindsorContainer();
container.Install(new MyWindsorInstaller());
var f = container.Resolve<ITcpServerFactory>();
var tcpServer = f.Create("standard", "something");
tcpServer.Start();
}
}
public class MyWindsorInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<ITcpServer>().ImplementedBy(typeof(LibUvTcpServer<>)),
Component.For<ITcpServer>().ImplementedBy(typeof(StandardTcpServer<>)),
Component.For<ITcpServerFactory>().AsFactory(c => c.SelectedWith(new TcpServerComponentSelector()))
);
}
}
public class TcpServerComponentSelector : DefaultTypedFactoryComponentSelector
{
protected override Type GetComponentType(System.Reflection.MethodInfo method, object[] arguments)
{
var serverType = (string)arguments.First();
return serverType == "standard" ? typeof (StandardTcpServer<>) : typeof(LibUvTcpServer<>);
}
}
public interface ITcpServerFactory
{
ITcpServer Create<T>(string serverType, T something);
}
public class StandardTcpServer<T> : ITcpServer
{
public void Start()
{
Console.WriteLine("Started...");
}
}
public class LibUvTcpServer<T> : ITcpServer
{
private readonly T something;
public LibUvTcpServer(T something)
{
this.something = something;
}
public void Start()
{
Console.WriteLine("Started...");
}
}
public interface ITcpServer
{
void Start();
}
Any help in solving the problem would be appreciated.
Change the following:
protected override Type GetComponentType(System.Reflection.MethodInfo method, object[] arguments)
{
var serverType = (string)arguments.First();
if (serverType == "standard")
{
return typeof(StandardTcpServer<>).MakeGenericType(arguments[1].GetType());
}
else
{
return typeof(LibUvTcpServer<>).MakeGenericType(arguments[1].GetType());
}
}
and the registration:
Component.For<ITcpServer>().Forward(typeof(LibUvTcpServer<>)).ImplementedBy(typeof(LibUvTcpServer<>)),
Component.For<ITcpServer>().Forward(typeof(StandardTcpServer<>)).ImplementedBy(typeof(StandardTcpServer<>)),
or if you only need to resolve through the factory:
Component.For(typeof(LibUvTcpServer<>)),
Component.For(typeof(StandardTcpServer<>)),
Good luck,
Marwijn.
Here is the annotation:
#Target(value = ElementType.TYPE)
#Retention(value = RetentionPolicy.RUNTIME)
#Inherited
public #interface MyAnnotation {
String name();
}
Here is one annotated class:
#MyAnnotation(name="foo")
public class ClassA {
public ClassA() {
// Do something
}
}
Here is a second annotated class:
#MyAnnotation(name="bar")
public class ClassB {
public ClassB(String aString) {
// Do something
}
}
I am looking for an aspectj pointcut that correctly matches the constructors for ClassA and ClassB while not matching any other constructor for any other class NOT annotated by MyAnnotation.
Your pointcut should look like this:
execution((#MyAnnotation *).new(..))
If the annotation is in another package:
execution((#de.scrum_master.aop.demo.MyAnnotation *).new(..))
Or if you do not want to fully qualify the package:
execution((#*..MyAnnotation *).new(..))
Edit: Okay, some more info about your question in the comment:
Constructor executions have no return value which you could capture in
after() returning(Object myObject) : myJoinpoint()
This only works for methods. So please use
after(Object myObject) returning : myJoinpoint() && this(myObject)
instead if you do need the constructed object for any purpose.
Here is the working solution from kriegaex in its entirety:
public aspect AnnotationTests {
public aspect AnnotationTests {
after(Object myObject) returning : execution((#MyAnnotation *).new(..))
&& this(myObject) {
System.out.println("Object class name: " + myObject.getClass().getName());
}
}
}
#MyAnnotation(name="foo")
public class ClassA {
public ClassA() {
// Do something
}
public static void main(String[] args) {
ClassA classA = new ClassA();
ClassB classB = new ClassB("");
if (classA.getClass().getName().equals(classB.getClass().getName())) {
throw new RuntimeException("Big problems!");
}
}
}
#MyAnnotation(name="bar")
public class ClassB {
private final String aString;
public ClassB(String aString) {
this.aString = aString;
}
}
THE FOLLOWING WORKS, BUT IS NOT RECOMMENDED BY kriegaex. PROVIDED HERE AS POSSIBLE MATERIAL THAT COULD BE REPURPOSED IF THE NEED ARISES.
This was my first working solution to the problem which uses in part the initialization() pointcut primitive.
public aspect AnnotationTests {
private pointcut genericConstructor(): initialization(*.new(..));
private pointcut withinMyAnnotation(): #within(MyAnnotation);
private pointcut constructorInAnnotatedClass(): genericConstructor()
&& withinMyAnnotation();
before(): constructorInAnnotatedClass() && !cflowbelow(constructorInAnnotatedClass()) {
final Object objectInstance = thisJoinPoint.getTarget();
System.out.println("Object class name at join point: "
+ objectInstance.getClass().getName());
}
}
#MyAnnotation(name="foo")
public class ClassA {
public ClassA() {
// Do something
}
public static void main(String[] args) {
ClassA classA = new ClassA();
ClassB classB = new ClassB("");
if (classA.getClass().getName().equals(classB.getClass().getName())) {
throw new RuntimeException("Big problems!");
}
}
}
#MyAnnotation(name="bar")
public class ClassB {
private final String aString;
public ClassB(String aString) {
this.aString = aString;
}
}
When _fwf.GetFileWatcher is called, always MailWatcher is returning. How can I return FileWatcher class with typed factory facility? I tried code block as below but this gets always the first component.
Also I tried DefaultTypedFactoryComponentSelector but i can't get a result.
public interface IWatcher : IDisposable
{
void StartWatching();
}
public class MailWatcher : IWatcher
{
public void StartWatching()
{
Console.WriteLine("Mail watcher");
}
public void Dispose()
{
throw new NotImplementedException();
}
}
public class FileWatcher : IWatcher
{
public void StartWatching()
{
Console.WriteLine("File watcher");
}
public void Dispose()
{
throw new NotImplementedException();
}
}
public interface IFileWatcherFactory : IDisposable
{
IWatcher GetWatcher(string path);
void Destroy(IWatcher fw);
}
public class Bootstrapper
{
private static WindsorContainer _container;
private static IFileWatcherFactory _fwf;
public static void Initialize()
{
_container = new WindsorContainer();
_container.AddFacility<TypedFactoryFacility>();
_container.Register(Component.For<IWatcher>().ImplementedBy<MailWatcher>().LifeStyle.Transient);
_container.Register(Component.For<IWatcher>().ImplementedBy<FileWatcher>().LifeStyle.Transient);
_container.Register(Component.For<IFileWatcherFactory>().AsFactory(x => x.SelectedWith(new FileWatcherSelector())));
_fwf = _container.Resolve<IFileWatcherFactory>();
strong textvar fw = _fwf.GetFileWatcher("file", 20);
fw.StartWatching();
}
}
For anyone looking at this, using the TypedFactoryFacility, to dictate which type the Factory will create if this varies, you can use the Get[Name] convention, where your interface will have a create method for each implementation type.
public class MailWatcher : IWatcher
{
public void StartWatching()
{
Console.WriteLine("Mail watcher");
}
public void Dispose()
{
throw new NotImplementedException();
}
}
public class FileWatcher : IWatcher
{
public void StartWatching()
{
Console.WriteLine("File watcher");
}
public void Dispose()
{
throw new NotImplementedException();
}
}
public interface IFileWatcherFactory : IDisposable
{
IWatcher GetMailWatcher(string path);
IWatcher GetFileWatcher(string path);
void Destroy(IWatcher fw);
}
public class Bootstrapper
{
private static WindsorContainer _container;
private static IFileWatcherFactory _fwf;
public static void Initialize()
{
_container = new WindsorContainer();
_container.AddFacility<TypedFactoryFacility>();
_container.Register(Component.For<IWatcher>().ImplementedBy<MailWatcher>().Named("MailWatcher").LifeStyle.Transient);
_container.Register(Component.For<IWatcher>().ImplementedBy<FileWatcher>().Named("FileWatcher").LifeStyle.Transient);
_container.Register(Component.For<IFileWatcherFactory>().AsFactory());
_fwf = _container.Resolve<IFileWatcherFactory>();
var fw = _fwf.GetFileWatcher("file", 20);
fw.StartWatching();
}
}
For more information, please refer to :
http://docs.castleproject.org/Windsor.Typed-Factory-Facility-interface-based-factories.ashx#Get_methods_lookup_components_by_name_4
I run this at the application Start Up
public class ConfigurationFacility : AbstractFacility {
private readonly List<string> configuredComponents = new List<string>();
protected override void Init() {
Kernel.ComponentRegistered += OnComponentRegistered;
// add environment configurators
}
private void OnComponentRegistered(string key, IHandler handler) {
// if the component is a configurator then run conf settings and add it to configuredComponents
}}
Question: How to hook tear down and to call explicit release for each ?
Thanks
You can use either the ComponentDestroyed event of IKernel or just implement IDisposable in your components. Here's a little sample code:
namespace WindsorInitConfig {
[TestFixture]
public class ConfigurationFacilityTests {
[Test]
public void tt() {
OneDisposableComponent component = null;
using (var container = new WindsorContainer()) {
container.AddFacility<ConfigurationFacility>();
container.AddComponent<OneDisposableComponent>();
component = container.Resolve<OneDisposableComponent>();
}
Assert.IsTrue(component.Disposed);
Assert.Contains(component, ConfigurationFacility.DestroyedComponents);
}
public class OneDisposableComponent : IDisposable {
public bool Disposed { get; private set; }
public void Dispose() {
Disposed = true;
}
}
public class ConfigurationFacility : AbstractFacility {
private readonly List<string> configuredComponents = new List<string>();
public static readonly ArrayList DestroyedComponents = new ArrayList();
protected override void Init() {
Kernel.ComponentRegistered += OnComponentRegistered;
Kernel.ComponentDestroyed += Kernel_ComponentDestroyed;
// add environment configurators
}
private void Kernel_ComponentDestroyed(ComponentModel model, object instance) {
DestroyedComponents.Add(instance);
// uninitialization, cleanup
}
private void OnComponentRegistered(string key, IHandler handler) {
// if the component is a configurator then run conf settings and add it to configuredComponents
configuredComponents.Add(key);}
}
}
}
The static ArrayList is only for demo purposes, of course.