Windsor ResolveAll and multiple UsingFactoryMethod - castle-windsor

I have next code:
var container = new WindsorContainer()
.Register(Component.For<IAppender>().UsingFactoryMethod(x=>new EventLogAppender()))
.Register(Component.For<IAppender>().UsingFactoryMethod(x=>new ConsoleAppender()));
var appenders = container.ResulveAll<IAppender>();
It fails with KernelException "Could not instantiate custom activator" in Seccond Register line.
I need to configure each Appender separately.
Who can help me to avoid this exception?

I don't know why but if I add Named() to at least one of Registration clause it will fix issue. Looks like a bug.

Related

How to fix Glass Mapper error - failed to find configuration for parent item type?

I have a Sitecore 8.1 CD instance. I also have some code that needs to create a content item in the Master database. (I am aware that is a no-no but I just need to figure this out at the moment) When my code attempts to use Glass Mapper to create a content item I get an error. Here is the code snippet and the error message. I am just trying to understand what the error means. I have a sense that this is simply a configuration problem. This code works fine on our Sitecore CM server. So I am hoping that by simply adjusting the config on our CD server I can get this to work. So far I have re-enabled the Master entry in ConnectionStrings.config and in Sitecore.config. But that hasn't fixed this.
SitecoreService service = new SitecoreService("master");
SimpleAes aes = new SimpleAes();
using (new SecurityDisabler())
{
Item parentItem = Factory.GetDatabase("master").GetItem("/sitecore/content/Non Page Content/Account Information/Shipping Addresses");
newAddress = service.Create(parentItem, newAddress); //THIS IS WHERE THE CODE FAILS
user.Addresses.Add(newAddress);
Utility.PublishItem(service.ResolveItem(newAddress));
id = aes.EncryptToString(newAddress.Id.ToString());
user.Addresses = user.Addresses;
user.Save();
}
Error Message:
Glass.Mapper.MapperException: Failed to find configuration for parent
item type Sitecore.Data.Items.Item ---> System.NullReferenceException:
Object reference not set to an instance of an object. at
System.Object.GetType() at
Glass.Mapper.Context.GetTypeConfiguration[T](Object obj, Boolean
doNotLoad, Boolean checkBase) at
Glass.Mapper.Sc.SitecoreService.Create[T,TK](TK parent, T newItem,
Boolean updateStatistics, Boolean silent) --- End of inner exception
stack trace --- at Glass.Mapper.Sc.SitecoreService.Create[T,TK](TK
parent, T newItem, Boolean updateStatistics, Boolean silent)
It is failing on this line
Item parentItem = Factory.GetDatabase("master").GetItem("/sitecore/content/Non Page Content/Account Information/Shipping Addresses");
if you put a check around it saying
if (parentItem != null) { // your code }
Then the code will work through and you will not get exception, but nothing will happen as well if parentItem is null.
Quick fix solution will be to give a 'master' DB connection string on your CD server (which is a no-no as you said). Better solution will be to expose master database through Sitecore Item API or your custom API, securing it through authentication and then calling this code from CD server via API.
I am not sure if you still are looking how to solve this issue, but when I faced today with it I found your question.
Problem is that your parentItem has type Item. It causes issue inside in Glass.
You can use any type as parent, but limitation is that it should not be inherited from Sitecore Item class.
Try this:
var parentItem = Factory.GetDatabase("master").GetItem("/sitecore/content/Non Page Content/Account Information/Shipping Addresses").GlassCast<BaseSitecoreItem>();
newAddress = service.Create(parentItem, newAddress);
where BaseSitecoreItem is some your Glass Model.
It helped me and hope will help you.

Execute a function in the context of another cfc in ColdFusion while honoring import statements

Background
I'm trying to create a function componentFromJson that can reconstitute a component graph from JSON. I took a simple approach where I'm using getMetaData in order to lookup the component properties to instantiate the right types.
The function would be used like: comp = componentFromJson(json, 'RootComponentType')
Problem
The problem is that the type of the properties are not necessarily fully qualified because namespaces may have been imported, as we can see below.
<cfimport path="some.namespace.Test">
<cfcomponent>
<cfproperty name="test" type="Test">
</cfcomponent>
When I'm trying to do createObject('Test') from the componentFromJson function context it's obviously failing because the calling context doesn't have the imports.
I have tried many different ways to resolve the problem, including temporarily defining the component factory function on the parent component dynamically and using invoke to call the factory function in the context of the parent CFC, but it doesn't work.
E.g.
<cfscript>
parentCmp = createObject('SomeCmp');
parentCmp.createComponent = function (type) {
return createObject(type);
};
childCmp = invoke(parentCmp, 'createComponent', { type = 'Test' });
</cfscript>
Horrible solution
The only way I can think of solving this issue right now is to parse the ColdFusion code of the CFC and extract the import statements, but I'm expecting this to be way too slow for the purpose. Not only that but this wouldn't cover all edge cases.
Ideas?
I'd like to know if someone has a better idea for solving this issue? Is there an entirely different approach I could take? There is probably a way to do this using the ColdFusion runtime classes, but I haven't figured it out yet.
Well, it turns out that it wasn't so hard when you knew the underlying mechanics of the ColdFusion runtime (which I had trouble to find initially).
I finally discovered that a ColdFusion component, which is represented as a coldfusion.runtime.TemplateProxy was encapsulating a coldfusion.runtime.CFPage instance which in turns has a createObject method.
Therefore, here's the solution I came up with using Java reflection:
<cfset host = new SomeComponent()>
<cfset pageField = createObject('java', 'coldfusion.runtime.TemplateProxy').getClass().getDeclaredField('page')>
<cfset pageField.setAccessible(true)>
<cfset page = pageField.get(host)>
<cfset test = page.createObject('Test')>

Invalid method when method is valid

I have just started a new version of my Crysis Wars Server Side Modification called InfinityX. For better management, I have put the functions inside tables as it looks neater and I can group functions together (like Core.PlayerHandle:GetIp(player)), but I have ran into a problem.
The problem is that the specified method to get the players' name, player:GetName() is being seen as an invalid method, when the method actually is completely valid.
I would like to know if using the below structure is causing a problem and if so, how to fix it. This is the first time I've used this structure for functions, but it is already proving easier than the old method I was using.
The Code:
Event =
{
PlayerConnect = function(player)
Msg.All:CenteredConsole("$4Event$8 (Connect)$9: $3"..player:GetName().." on channel "..player.actor:GetChannel());
System.LogAlways(Default.Tag.."Incoming Connect on Channel "..player.actor:GetChannel());
Event:Log("Connect", player);
end;
};
The below code works when I bypass the function and put the code directly where it's needed:
Msg.All:CenteredConsole("$4Event$8 (Connect)$9: $3"..player:GetName().." on channel "..player.actor:GetChannel());
System.LogAlways(Default.Tag.."Incoming Connect on Channel "..player.actor:GetChannel());
The Error:
[Warning] [Lua Error] infinityx/main/core.events.lua:23: attempt to call method 'GetName' (a nil value)
PlayerConnect, (infinityx/main/core.events.lua: 23)
ConnectScript, (infinityx/main/core.main.lua: 52)
OnClientEnteredGame, (scripts/gamerules/instantaction.lua: 511)
(null) (scripts/gamerules/teaminstantaction.lua: 520)
Any clarification would be appreciated.
Thanks :)
Well, as PlayerConnect is inside the table Event, and you are calling with a ":", add self as first arg in the function, like:
PlayerConnect = function(self, player)
Clearly, player in the first block of code is not the same as player in the second block of code. The problem must be that the caller of Event.PlayerConnect is not passing the same value.
To test that your Event.PlayerConnect function works, try this in the same place as your second block of code:
Event.PlayerConnect(player)
That should work as you expect.
So, the problem comes down to how Event.PlayerConnect is called without the second block of code. I'm not familiar with that game engine so I don't know how it is done. Perhaps reviewing the documentation and/or debugging that area would help. If you print(player) or call the equivalent log function in both cases, you should see they are different. If you can't run in a debugger, you can still get a stack trace with print(debug.traceback("Accessing player, who's value is: "..player)). If there is indeed some kind of table-based player object in both cases, you can try comparing their fields to see how they are different. You might need to write a simple dumping function to help with that.

AS3: odd instance name behavior when removing

So i have narrowed down my problem to this:
i have two instances of a movieclip ("content1", "content2") added into two different other movieclips ("container1", "container2"). I want to remove them.
As soon as i remove one of them with this horrible command...
MovieClip(MovieClip(root).getChildByName("container1")).removeChild(MovieClip(MovieClip(root).getChildByName("container1")).getChildByName("content1"));
...the other instance of it changes its instance name to a generic one (like "instance25") and i can't access it anymore with getChildByName.
Can anyone explain this please?
I've never experienced that behaviour - regardless, what you can do is store reference to both before you remove them. This way, you won't need their original instance name to remove both:
var top:MovieClip = root as MovieClip;
var cotainer:MovieClip = top.container1;
var content1:MovieClip = container.getChildByName("content1");
var content2:MovieClip = container.getChildByName("content2");
container.removeChild(content1);
container.removeChild(content2);
Hopefully this answer gives you some hints for making your code much more readable as well.

Adding state to bean generated via CGLIB's BeanGenerator

I see the following example code on how a Java Bean can be created dynamically. What I am not able to figure out is how I can update the state of an instance once created.
So in the following example how can I set the value of foo to "footest" for instance bean?
BeanGenerator bg = new BeanGenerator();
bg.addProperty("foo", Double.TYPE);
bg.addProperty("bar", String.class);
Object bean = bg.create();
Thanks
Kumar
A few ways come to mind:
1/ Call "setFoo()" on "bean" using reflection. Not pretty.
2/ Use a helper library to do the same thing - e.g. Commons-Beanutils o.a.c.BeanUtils.PropertyUtils.setProperty(bean, "foo", "footest").
This way works nicely for me. You could use the Spring equivalent if you're already using Spring.
3/ Use CGLIB's BeanMap upon your new bean. e.g.
Map beanMap = BeanMap.create(bean);
beanMap.put("foo", "footest");