Is there a way to change private static field of an alien class?
For example:
package mx.managers {
public class TooltipManager ... {
private static var _impl:IToolTipManager2; // <- assign my own value here
...
}
}
In Java it is possible to do it using Reflection API. What about Flex?
No, that is not possible.
If you are looking into changing the implementation of the TooltipManager, have a look at the Singleton class in the Flex SDK. You'll need to create a custom implementation and register it via the Singleton class before the application initializes. The best is to override the application preloader and do the registration there.
Well, if you feel like you can handle the extra responsibility, you can monkey patch the class by copying the source into your own source tree with the same package and apply the necessary modifications. That way the flex compiler will use your implementation rather than the SDK implementation.
This technique is sometimes used as a last resort to fix issues which cannot be fixed otherwise. Drawbacks include issues such as forwards compatibility and unintended side effects in the same or other classes dependant on the class your editing.
Related
I just started using Caliburn.Micro and I've noticed in all the examples that the methods are all public. I decided to test this by adding a button with:
x:Name="CloseMainWindow"
In my VM I added a method:
private void CloseMainWindow()
{
TryClose();
}
When I click the button, nothing happens and I don't hit the breakpoint, but if I change the method to public it works.
I can't see this being the best way to do this.
Would creating ICommand properties for all the methods be an acceptable solution?
Edit: I just read the answer to the question immediately above, there is not and never will be ICommands in Caliburn.Micro. So my original question still needs an answer, why does everything have to be public in the VM and is this safe?
I don't know what you mean by "is this safe?". Safer than what?
Anyway, Caliburn.Micro could have been designed to allow its conventions to bind to private methods, but that has a couple of drawbacks. First, it wouldn't work in partial-trust environments, like Silverlight or XBAPs or sandboxed plugins. You need full trust to use Reflection to access private members, and Caliburn.Micro is designed to be able to run in partial-trust (it does support Silverlight, after all).
But a bigger reason is that it would violate encapsulation. These are methods that you intend to be called from outside the class. (The view is a separate class, after all; you'd have to make the viewmodel method public if you were wiring it up yourself in the code-behind.) There's a word for "I intend to call this from outside my own class" in the language specification, and that's public. If you set up some magic that calls private methods from outside the class, you're violating both encapsulation and the Principle of Least Astonishment, because that's not what private means.
If you really want to be able to bind to private methods, you can customize the conventions. But it would make your code much harder to understand, so I wouldn't recommend it unless you can come up with a really good justification.
I want to extend or copy the PopUpManager class to add the ability to keep track of the number of windows.
I just want to add a simple windowCount++ when a window is added and windoCount-- when it's removed.
the problem is PopUpManager is a Singleton class... I wasn't able to make it work properly by extending it. And now I have tried to copy the code from the PopUpManager.as file and just add my variable to the end of its functions. It doesn't seem to be working though since it says my properties are undefined even though they are declared above the constructor.
I am thinking I would have to make a copy of the PopUpManagerImpl.as since that's wehre it seems much of the business resides (PopUpManagerImpl extends EventDispatcher implements IPopUpManager) would that allow me to have access to the variable? and should I ignore the manager and just put it in the implementation class?
here is a link about Using the Flex Singleton register, which helped me out when finding myself in the same situation.
I hope you can inspire from that too.
You likely didn't declare yours properties as static. The PopUpManager uses all static methods - this is why working with it you use syntax like:
PopUpManager.createPopUp(...
instead of
var popUpManager:PopUpManager = new PopUpManager();
popUpManager.createPopUp(...
This means that any variables declared in the PopUpManager need to also be static so as to be accessible at the class level.
public static var windowCount:int
I'm trying to have all my views inherit from a custom class so that I can add certain behaviour and values to all pages, but I'm having some issues. I tried subclassing System.Web.Mvc.WebViewPage but I'm forced to implement an Execute procedure that I don't know what it should do. Also, if I try to access the Context variable, I get a null reference (really weird). This leads me to think that I may have the wrong base class....
Any thoughts?
Diego, System.Web.Mvc.WebViewPage is the right base type (and you should have another class inheriting from System.Web.Mvc.WebViewPage<TModel> if you want strongly-typed views). You should mark your own class as abstract so that you are not forced to implement the Execute method.
Update: To configure all your views to use your custom base class, look into the ~\Views\Web.config file. Inside of it there's a Razor-specific section where you can use the pageBaseType attribute to configure your custom type.
As far as the Context property is concerned, it should be fully initialized once the view is executing. However, it might not be available if you try to access it too early (for example, from your classes constructor). When are you trying to access it?
The Execute method is something that is provided by the Razor compiler when your view is compiled. For example, given the following view file
Hello #Name!
The Razor compiler will behind the scenes generate the following class (this is a simplification, so the details might be off, but it should convey the point)
public class _Some_Generated_Class_Name_ : System.Web.Mvc.WebViewPage {
public void Execute() {
Write("Hello ");
Write(Name);
Write("!");
}
}
Then the framework calls the Execute method on your view class and your view gets executed.
I'm still pretty new to using Autofac and one thing I miss in the documentation and examples is how to make it easy to get to the configured container from different places in a web application.
I know I can use the Autofac controller factory to automatically resolve constructor injected dependencies for controllers, but how about the other stuff you might need to resolve that is not injected yet.
Is there an obvious pattern I am not aware of for this?
Thank you!
The Autofac "way" is to have an IContext constructor parameter. Autofac will inject an object that can be used to resolve types.
The context is usually the container behind the scenes, IContainer implements the IContext interface, though IContext is limited to only doing resolves.
I know that the container should not be "overused", but I have, as the OP, classes that requires resolving types that is not known ahead of time (and thus cannot be used as constructor params). I find it useful in these cases, to think of the container as yet another service that can be used to resolve other services, and inject that like any other service.
If you feel that using IContext binds you to Autofac and you need to abstract that with your own interface this is just a matter of registering an IContext wrapper class with your container.
Update: in Autofac 2, the IContext is called IComponentContext.
First of all try not to overuse the IoC container. Its great for "wiring up" controllers, views and services but objects that need to be created during runtime should be created by factory objects and not by the container. Otherwise you get Container.Resolve calls all through your code, tying it to your container. These extra dependencies defeat the purpose of using IoC. In most cases I can get by only resolving one or two dependencies at the top level of my application. The IoC container will then recursively resolve most dependencies.
When I need the container elsewhere in my program here's a trick I often use.
public class Container : IContainer
{
readonly IWindsorContainer container;
public Container()
{
// Initialize container
container = new WindsorContainer(new XmlInterpreter(new FileResource("castle.xml")));
// Register yourself
container.Kernel.AddComponentInstance<IContainer>(this);
}
public T Resolve<T>()
{
return container.Resolve<T>();
}
}
I wrap the container in a Container class like this. It adds itself to the wrapped container in the constructor. Now classes that need the container can have an IContainer injected. (the example is for Castle Windsor but it can probably be adapted for AutoFac)
Having IOC container globally available is not a best practice. Even passing container is not encouraged.
If dependency injection can not be used (you need to create\request objects after component has been created) then you can:
Use hand-coded factories (factory is injected to the component and component uses factory to create other objects)
Use Autofac delegate factories or new auto-generated factories in Autofac 2.
Peter Lillevold's response above is correct - you can access the container from any component by taking a dependency on the IContext interface.
If you really do need the actual container reference, see Autofac.Integration.Web.IContainerProviderAccessor.
The usual way of doing this is to store the container in a static variable in your Global app class.
Does anyone know if it is possible to inject into a regular as3 (non mxml) class? I've tried with limited success.
Thanks
Could you be more specific? There's no difference between an "MXML" class and a class defined in ActionScript, it's just different ways of writing the same thing.
All that is needed for injection to work is a source property that is bindable and a destination property that is public (either a public setter or a public instance variable). If those two requirements are met and the code compiles it should work.
Look at the code for the example application you can find here: http://code.google.com/p/mate-examples/wiki/DocumentBasedExampleIntro and you will find a ton of injectors that target classes not defined using MXML (look for injectors targeting classes whose names end in "Model" especially). You can also find countless examples in the Mate forums.