Castle Windsor bug: Resolving singleton through child container - castle-windsor

This fails with an ObjectDisposedException when trying to assert:
[Test]
public void Resolve_SingletonAndDisposeChildContainer_ShouldNotDisposeSingleton()
{
// arrange
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<ISomeFactory>().AsFactory());
container.Register(Component.For<A>());
// uncomment the line below and the test will not fail
//container.Resolve<ISomeFactory>();
var childContainer = new WindsorContainer();
container.AddChildContainer(childContainer);
// act
var someFactory = childContainer.Resolve<ISomeFactory>();
container.RemoveChildContainer(childContainer);
childContainer.Dispose();
someFactory = container.Resolve<ISomeFactory>();
// assert
Assert.That(someFactory.Create(), Is.Not.Null);
}
The reason is (probably) because the singleton is handled by the lifestylemanager in the child container and is therefore disposed. This is causing some issues with child-container handling in the MVC Web API, so I am really keen on finding a solution.
Does anyone know of a clean solution to this problem?

This is indeed a bug. I put it in the issue tracker. It is fixed in trunk and will be fixed in v3.1

Related

Castle.Windsor Unable to Inject Dependencies from external DLL

I am using Windsor Castle as IoC tool. and uptill now I am able to inject dependencies into the targeted class easily. However what I am trying to do (and unable to do) is to inject single or multiple dependencies which are part of external DLLs loaded through reflection, but when I call the Resolve method of Container then it throws exception that:
Can't create component 'ClassLibrary3.MainClass' as it has dependencies to be satisfied.
Following is the peice of code that I am using
var assembly = Assembly.LoadFile(assemblyFullPath);
var type = assembly.GetType(fullyQualifiedClassName);
var container = new WindsorContainer();
container.Register(Component.For(type));
var dependecyInterfaceAssembly = Assembly.LoadFile("<SomePath>\\ClassLibrary3.dll");
var dependecyInterfaceType = dependecyInterfaceAssembly.GetType("ClassLibrary3.IDependency3");
var dependecyImplementationAssembly = Assembly.LoadFile("<SomePath>\\ClassLibrary3.dll");
var dependecyImplementationType = dependecyImplementationAssembly.GetType("ClassLibrary3.Dependency3");
container.Register(Component.For(dependecyInterfaceType).ImplementedBy(dependecyImplementationType));
return (IJob) container.Resolve(type);
So container calls the Resolve function it is throwing exception
Can't create component 'ClassLibrary3.MainClass' as it has dependencies to be satisfied.
'ClassLibrary3.MainClass' is waiting for the following dependencies:
- Service 'ClassLibrary3.IDependency3' which was not registered.
On the other hand I know for sure that all of its dependencies are referenced correctly (Path and Class names are checked).
Thanks in advance.

No Such Field Error : useGL20

So I upgraded to the latest nightly and updated my project to remove all calls to GL10 but I am getting this error even though I have removed the reference to it.
Exception in thread "main" java.lang.NoSuchFieldError: useGL20
at com.me.mygdxgame.Main.main(Main.java:10)
This is what the code in the file looks like
package com.me.mygdxgame;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
public class Main {
public static void main(String[] args) {
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
cfg.title = "my-gdx-game";
// cfg.useGL20 = false;
cfg.width = 480;
cfg.height = 320;
new LwjglApplication(new MyGdxGame(), cfg);
}
}
Does anyone have an idea of why I still keep getting this error?
The latest libgdx build has gotten rid of the opengl 1.0 backend so the field cfg.useGL20 is no longer needed. If interested read up here
According to that page
LwjglApplicationConfiguration and AndroidApplicationConfiguration do not have the useGL20 flags anymore.
So eliminate that line and things should be good if you updated each project to the newest nightely. If you are still having problems update projects again to the newest nightly as this is very new to libgdx so there are probably a lot of bugs

RootFrame UriMapper for Caliburn Micro

I have been googling on how to actually implement this with no avail. Could not find a single resource on how to actually do it using Caliburn Micro.
Basically, I am trying this http://www.developer.nokia.com/Community/Wiki/OAuth_on_Windows_Phone
In the example, it used redirect_uri as normal link. I did it with Protocol/File Association (refer http://www.developer.nokia.com/Community/Wiki/URI_associations_for_Windows_Phone_8). Everything works fine. I got it to work without Caliburn Micro.
But based on that example, I would require to implement UriMapperBase and assigned it to RootFrame.UriMapper.
My question is how do I actually implement UriMapper with CaliburnMicro for WP8. For Win 8, it is different as I could override the OnActivate and check for the ActivationKind.Protocol and there is no need for UriMapper.
Ok. Finally managed to get it to work. So, will post it here because I'm pretty sure there will be a lost soul again like me who will appreciate the answer to this.
To use UriMapper in Caliburn, you will need to override the CreatePhoneApplicationFrame in the bootsrapper.
In Boostrapper.cs
protected override PhoneApplicationFrame CreatePhoneApplicationFrame()
{
// var frame = base.CreatePhoneApplicationFrame(); this doesnt work
var frame = new PhoneApplicationFrame(); // this works
frame.UriMapper = new AssociationUriMapper();
return frame;
}
AssociationUriMapper.cs - I just followed the example as per links above
public class AssociationUriMapper : UriMapperBase
{
private string tempUri;
public override Uri MapUri(Uri uri)
{
tempUri = System.Net.HttpUtility.UrlDecode(uri.ToString());
// URI association launch for contoso.
if (tempUri.Contains("pocketthis:MainPage"))
{
// Get the category ID (after "CategoryID=").
//int categoryIdIndex = tempUri.IndexOf("CategoryID=") + 11;
//string categoryId = tempUri.Substring(categoryIdIndex);
// Views/MainPage.xaml returns external exception,
// so remember the / before views
return new Uri("/Views/MainPage.xaml", UriKind.Relative);
}
// Otherwise perform normal launch.
return uri;
}
}
Hope this will help anyone trying to implement Uri/File Association in WP8 with Caliburn Micro.

Why does a closed NetConnection that has no event listeners or references stick around in memory?

It seems that if flash.net.NetConnection is instantiated and connected to an HTTP URL (such as an AMFPHP gateway), that instance is never picked up by garbage collection even after it has been closed and the only reference is set to null.
On the other hand, if the instance is connected to null (as would be done when used to play video/mp3 files), the instance is cleared from memory.
To clarify, the following connection will stick around in memory:
var stickyConn:NetConnection = new NetConnection();
stickyConn.connect("http://myserver/amfphp/gateway.php");
stickyConn.close();
stickyConn = null;
Whereas, the following connection will be cleared from memory immediately:
var tempConn:NetConnection = new NetConnection();
tempConn.connect(null);
tempConn.close();
tempConn = null;
Some things I have already tried to solve this issue:
set the client to an empty object (since the default value of the client is the NetConnection itself)
before closing the connection, call connect(null)
after closing the connection, call connect(null) and close it again
Has anyone run into this issue before? Is there a solution to this?
I have built heavyloaded FLV/Mp4 Players using AS3 quite often. When I am using a service like Akamai or Adobe's internal NetConnection Class I always keep in mind the
client object.
the is the property of NetConnection on which ALL callback methods are invoked. The default is this NetConnection instance this. If you set the client property to another object, callback methods will be invoked on that object.
In this way you can easily understand how Garbage Collection was never really applied accross each component in the same way. So, where stickyConn = null; only stops the playback, since you never declared a Weak Reference, Garbage Collection has no clue what to look for.
I have had success with differrent methods based on the specific player:
Simply stating NetConnectionObj.client = this usually suffices. But what if your NetConnection is extended or implementing an interface? Simply use a null Dictionary object:
var d:Dictionary = new Dictionary(true); . From here Garbage collection will recognize "d" as a weak reference and automatically dump it;
Hence, your snippet will look somewhat like this:
var Dc:Dictionary = new Dictionary(true);
NetConnection:NetConnection.client = Dc;
or some variation with the same intent.
I know this works, so reach out if you need help...
I may have been vague with the last answer in regards to GC and Dictionary Objects. Please take this snippet into consideration. I wrote it quickly but I try to explain the Concept of what solves your problem; mainly since I have dealt with it before:
public class Main extends MovieClip {
private var connection:NetConnection;
private var __nData:*;
private var _instance:*;
private var _closure:Function;
private var _D:Dictionary;
public function Main() {
connection = new NetConnection();
connection.addEventListener(NetStatusEvent.NET_STATUS, _nsHandle)
connection.connect(null);
}
public function _nsHandle(event:NetStatusEvent):void {
try {
connection = new NetConnection();
connection.connect(null);
connection.client = RegisterForGC(event.target);
RegisterForGC(connection);
} finally {
__nData = event.target.netConnection;
}
}
public function RegisterForGC(NCObject:*):* {
_instance = NCObject;
_closure = function ():void {}
_listener = function (e:Event):void {}
_D = new Dictionary(true);
_D[_listener] = "A";
_D[_instance] = "B";
_D[_closure] = "C";
try {
new LocalConnection().connect( "A" );
new LocalConnection().connect( "B" );
} catch (anything:*) { }
return _instance;
}
}
I'm not sure but Your example seems to suggest you are declaring your vars on stage / frame.
close(); is all you need for this to work HOWEVER....
from what I have found with NetConnection it for some reason unless all vars / functions are declared in an External class eg. public vars public function,
It stays in memory even after using close();
Pulled out my hair figuring this out with an audio streaming project.
However once I moved all coding to an external class, close(); actually closed the connection.
If your code is on a frame on stage or within MC I would create a class and declare vars & functions in said External Class.as and for some stupid reason it works.
Hope this helps.
Are you using a NetStream object and not disposing of it when finished? I only ask because I rarely see a NetConnection without a NetStream object far behind it.

Trying to connect to AMFPHP - NetConnection.connect() returns TypeError: Error #1009

UPDATE: Now I've moved the AMFConnection var declaration to outside the functions in Main, and commented out some trace() commands, and now it gives new errors:
Error #2044: Unhandled NetStatusEvent:. level=error, code=NetConnection.Call.BadVersion
at AMFConnection/init()[/Users/Jan/Downloads/amfphp1/AMFConnection.as:32]
at AMFConnection()[/Users/Jan/Downloads/amfphp1/AMFConnection.as:23]
at Main/testConnection()[/Users/Jan/Downloads/amfphp1/Main.as:14]
at Main()[/Users/Jan/Downloads/amfphp1/Main.as:10]
All of these essentially point to AMFConnection's NetConnection initialisation: _netConnection = new NetConnection(); (where _netConnection is declared at the beginning of the class)
I'm trying to connect to AMFPHP on a server (with Flash AS3), and the swf borks when it reaches the .connect() stage. To make things easier (?) and more reusable (?), I've put all the NetConnection mechanics into a separate class, AMFConnection, which I call from the Main document class like this (details changed):
public function testConnection(e:*=null):void {
var conn:AMFConnection = new AMFConnection();
conn.table = "some_table";
conn.selections = "*";
conn.conditionals = "WHERE something = 'something'";
conn.service = "QueryAMF";
conn.method = "makeQuery";
conn.displayText = txt;
conn.gogogo("http://www.someplace.com/Amfphp");
}
AMFConnection actually starts the connection and calls the AMFPHP service with the function gogogo(), and here's where the connect() NetConnection function just won't work. Here's the main section of the AMFConncection class
private var _netConnection:NetConnection;
private var _responder:Responder;
function AMFConnection()
{
init();
}
private function init(e:* = null)
{
_netConnection = new NetConnection();
_responder = new Responder(uponResult);
}
public function gogogo(url:String):void {
trace(url);
_netConnection.connect(url);
_netConnection.call(String(service+"/"+method), new Responder(onResult, null), table, selections, conditionals);
}
A quick debug session reveals the below errors:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at AMFConnection/gogogo()[AMFConnection.as:44]
at Main/testConnection()[Main.as:20]
at Main()[Main.as:8]
Where: Main.as:20 = conn.gogogo(...), and AMFConnection.as:44 = _netConnection.connect(url);
It also fails to display the stage, instead showing the loading dots. Now, eventually I'm going to move this application to the same server as the AMFPHP service, but even when I try it there with a relative url, instead of an absolute one, it still breaks down at connect(). I've tried changing the publish settings from local only to network only, to no avail.
Any clues? Know a better way to connect to AMFPHP locally?
Cheers in advance!
JB
P.S. Post updated, see top of page.
first, i prefer to use a php file which contains my sql and params. but hey...
The most obvious reason why you might get this error would be a fault in the url i guess. I believe that the standaard gateway.php is written without a capital G. and does not situate itself in the core folder but in the amfphp folder. but then again I don't know what you have altered.
Your _netConnection must be null, and you call connect() method on null reference, so you finish with NullPointerException. Show us how you initialize _netConnnection :).
Ok, I basically remade the thing, and after a couple of hours, it decided to work. I'm not sure how, but... eh.
Thanks all for your help