I've searched and searched for info on how to load a custom static class in PowerShell but up to now no avail. I'm googled out. I've seen enougth info and samples on how to load custom classes that need to be instantiated or how to load .Net framework classes but not exactly what I'm looking for.
I'm trying to use a custom dll, written in C# with following structure:
namespace Custom.NameSpace
{
public static class AppCfgHelper
{
public static XmlNode SomeXmlNodeFunction( XmlNode xmlRoot )
{
...
}
}
}
Can anybody help please?
There are two steps. First load the assembly containing your static class e.g.:
Add-Type -Path <path-to-dll>
Then use invoke the static method using PowerShell's static method syntax [typename]::membername e.g.:
$returnedNode = [Custom.NameSpace.AppCfgHelper]::SomeXmlNodeFunction($rootNode)
Related
Trying to clean up some nasty code, for which we dont have the source code. Imagine something like this:
public class Driver{
private String paramA;
private String paramB;
new Driver(HugeAndOverbloatedObject object)
{
paramA = object.getSubObject4711().getParamX();
paramB = object.getSubObject4712().getParamY();
}
}
This third library has this all over the place: tight coupling via constructors, eventhough the classes are hardly related. The rude combination of private members and forced constructor inheritance make the extension of the code virtually impossible without creating "sloppy" constructor parameter objects.
So I am trying to manipulate the classes via AspectJ and compile time weaving, so I can slim down on the constructors, to something like this:
Driver driver = new Driver("paramA", "paramB");
I think this should be possible, and I have made some progress. If I have something like this:
public aspect NewConstructor {
Driver.new(String parameterA, String parameterB){
//New Constructor Code
}
}
and run this through the weaver I actually find a new constructor in the driver, but not quite as I expected.
Issue: Unexpected third Parameter in the woven class
I was hoping I can invoke it with two parameters:
new Driver("paramA", "paramB")
Instead I need to invoke it with three parameters:
new Driver("paramA", "paramB", new NewConstructor())
Why do I need to instantiate a new instance of the aspect and pass it as an argument? Can this be prevented?
Something odd is going on here. You should not need to add the aspect as a third argument to the constructor. In fact, when I try this myself using the following class and aspect, I do not get any compile errors:
Java class:
package pack;
public class Driver {
public static void main(String[] args) {
new Driver("paramA", "paramB");
}
}
Aspect:
package pack;
public aspect NewConstructor {
public pack.Driver.new(String parameterA, String parameterB){
}
}
Are your Java class and aspect in different projects? Are you using an aspect path and/or in path? Are you using load time weaving?
If after doing a full build of your project you still see the probem, it's worth raising a bug for AspectJ.
I want to use Powershell to insert entities into Azure Table Storage and therefore need to instantiate a class which derives from the .NET abstract class Microsoft.WindowsAzure.StorageClient.TableServiceEntity
I am thinking to instantiate (in a Powershell 2.0 script) an object using eg New-Object and then adding members using Add-Member but cannot achieve the instantiation of a compatible TableServiceEntity derived class. (I can instantiate other arbitrary PSObjects, but they won't do it seems)
Alternatively if someone could show me how to instantiate and populate ANY object class which could then be passed into the tableServiceContext.AddObject() method
What you can do is to create your class in a cs file and then reference it to your script.
Here's example:
Save this as a cs file:
using System.Collections;
public class MyList : System.Collections.Generic.List<string>
{
public static string Test(string input)
{
return string.Format("test input {0}", input);
}
}
And here's the code to run it:
cd c:\pst
Add-Type -Path "2.cs" #-ReferencedAssemblies $assembly
[MyList]::Test("aaa")
You might need to pass your assembly to ReferencedAssemblies . And you also might need to upload assemblies into your script
The way to create table is described here:
Add or replace entity in Azure Table Storage
I'm a beginner on IoC and dependency injection. I'm reading about it, but I just can't get it.
While I figure out how stuff works, I'm trying to implement some of these patterns on my project (and maybe learn by trial and error).
I'm implementing security control by using FluentSecurity package (from NuGet, btw). I need to implement a Policy Violation Handler, as described on this wiki. The problem is that the example is written for StructureMap IoC-container, and I'm using (or trying to) Ninject 2.2 (it seemed more simple for a beginner).
On their code, they suggest (a):
configuration.ResolveServicesUsing(type => ObjectFactory.GetAllInstances(type).Cast<object>());
And then (b):
public class WebRegistry : Registry
{
public WebRegistry()
{
Scan(scan =>
{
scan.TheCallingAssembly();
scan.AddAllTypesOf<IPolicyViolationHandler>();
});
}
}
My concerns:
I know that code (a) will be included on Global.asax. But what is Ninject's alternative to ObjectFactory.GetAllInstances()?
I have no idea neither where this code should be inserted nor what are the equivalents for WebRegistry, Scan, and the internal functions TheCallingAssembly and AddAllTypesOf.
I know this is a bit extensive question, but I appreciate any help! Thanks in advance.
Marius Schulz has written an excellent article that should help anyone wanting to use Ninject together with FluentSecurity.
Setting Up FluentSecurity to Use Ninject for Dependency Resolution
I think this would be roughly equivelent
//add an instance of IKernel to your MvcApplication
[Inject]
public IKernel Kernel { get; set; }
...
configuration.ResolveServicesUsing(type => Kernel.GetAll(type));
To get the ability to scan an assembly for dependencies you would need an extension for ninject called Ninject.Extensions.Conventions, which was modeled after the one from SM.
public class WebModule : NinjectModule
{
public WebModule()
{
Kernel.Scan(a => {
a.FromAssemblyContaining<YourType>();
a.BindWithDefaultConventions();
a.InTransientScope();
});
}
}
The assembly scanning business obviously isn't strictly necassary for what you're doing, this would work just as well. Personally I'm not a fan of assembly scanning because it seems a little too "magic", and when it doesn't work, it's not fun to debug.
Kernel.Bind<YourType>().ToSelf();
I had same problem like you had with Ninject. After hours of googling I downloaded the source code from github. I understood the code and debugged few methods to figured out how to resolve the services. All I have to do is provide a service locator to find the PolicyViolationException handlers.
Ninject equivalent seems to be like this.
configuration.ResolveServicesUsing(type => System.Web.Mvc.DependencyResolver.Current.GetServices(type));
I used Ninject MVC3 and I used below code to load the modules from my current MVC web project plus other assemblies.
private static void RegisterServices(IKernel kernel)
{
kernel.Load("*.dll");
//kernel.Load(Assembly.GetExecutingAssembly());
}
I configured PolicyViolationException handlers in my module:
public class MainWebNinjectModule : NinjectModule
{
public override void Load()
{
// other bindings here
Bind<IPolicyViolationHandler>().To<DenyAnonymousAccessPolicyViolationHandler>();
}
}
Other required dependencies like ISecurityHandler, ISecurityContext etc are resolved by the internal IoC used in FluentSecurity.
Let's say I have a contract
public interface IGreeting
{
string SayHelloWorld();
}
And a class in another dll
[Export(typeof(IGreeting))]
public class Greeting : IGreeting
{
public string SayHelloWorld()
{
return "GREETING V1";
}
}
I use directorycatalog to get this DLL. I works fine. When I update my source code like this:
[Export(typeof(IGreeting))]
public class Greeting : IGreeting
{
public string SayHelloWorld()
{
return "GREETING V2";
}
}
and put this new DLL "Next" to the old Greeting DLL Mef doesnt import multiple different Greeting classes but picks 1 out of 2 DLL and exports 2 times from the same class.
So final executing directory looks like this:
MyApp.exe
Greeting_V1.dll
Greeting_V2.dll
I want the application to import 2 Greeting classes with ImportMany. It gives me 2 instances from Greeting_V1.dll. If I delete Greeting_V2.dll it gives me only 1 instance of Greeting_V1.dll.
Well, to me, it looks like you are importing many instances of IGreeting, so in that sense, MEF is doing exactly what it is supposed to do. If you want to replace the instance of Greeting from the V1 assembly with what is in V2, remove the V1 assembly, that way MEF can only load what is available.
It not a MEF problem. The problem is in the loading model of .NET. (or better the way you're objects are loaded by .net)
When MEF loads it returns the correct objects. But when looking for class Greeting when V2 is loaded there is already a Greeting class for V1 dll loaded with the correct class Greeting name for V2 is referring to. And the loader the dll actually referenced by V2 is not loaded.
GWT.create() is the reflection equivalent in GWT,
But it take only class literals, not fully qualified String for the Class name.
How do i dynamically create classes with Strings using GWT.create()?
Its not possible according to many GWT forum posts but how is it being done in frameworks like Rocket-GWT (http://code.google.com/p/rocket-gwt/wiki/Ioc) and Gwittir (http://code.google.com/p/gwittir/wiki/Introspection)
It is possible, albeit tricky. Here are the gory details:
If you only think as GWT as a straight Java to JS, it would not work. However, if you consider Generators - Special classes with your GWT compiler Compiles and Executes during compilation, it is possible. Thus, you can generate java source while even compiling.
I had this need today - Our system deals with Dynamic resources off a Service, ending into a String and a need for a class. Here is the solutuion I've came up with - btw, it works under hosted, IE and Firefox.
Create a GWT Module declaring:
A source path
A Generator (which should be kept OUTSIDE the package of the GWT Module source path)
An interface replacement (it will inject the Generated class instead of the interface)
Inside that package, create a Marker interface (i call that Constructable). The Generator will lookup for that Marker
Create a base abstract class to hold that factory. I do this in order to ease on the generated source code
Declare that module inheriting on your Application.gwt.xml
Some notes:
Key to understanding is around the concept of generators;
In order to ease, the Abstract base class came in handy.
Also, understand that there is name mandling into the generated .js source and even the generated Java source
Remember the Generator outputs java files
GWT.create needs some reference to the .class file. Your generator output might do that, as long as it is referenced somehow from your application (check Application.gwt.xml inherits your module, which also replaces an interface with the generator your Application.gwt.xml declares)
Wrap the GWT.create call inside a factory method/singleton, and also under GWT.isClient()
It is a very good idea to also wrap your code-class-loading-calls around a GWT.runAsync, as it might need to trigger a module load. This is VERY important.
I hope to post the source code soon. Cross your fingers. :)
Brian,
The problem is GWT.create doen't know how to pick up the right implementation for your abstract class
I had the similar problem with the new GWT MVP coding style
( see GWT MVP documentation )
When I called:
ClientFactory clientFactory = GWT.create(ClientFactory.class);
I was getting the same error:
Deferred binding result type 'com.test.mywebapp.client.ClientFactory' should not be abstract
All I had to do was to go add the following lines to my MyWebapp.gwt.xml file:
<!-- Use ClientFactoryImpl by default -->
<replace-with class="com.test.mywebapp.client.ClientFactoryImpl">
<when-type-is class="com.test.mywebapp.client.ClientFactory"/>
</replace-with>
Then it works like a charm
I ran into this today and figured out a solution. The questioner is essentially wanting to write a method such as:
public <T extends MyInterface> T create(Class<T> clz) {
return (T)GWT.create(clz);
}
Here MyInterface is simply a marker interface to define the range of classes I want to be able to dynamically generate. If you try to code the above, you will get an error. The trick is to define an "instantiator" such as:
public interface Instantiator {
public <T extends MyInterface> T create(Class<T> clz);
}
Now define a GWT deferred binding generator that returns an instance of the above. In the generator, query the TypeOracle to get all types of MyInterface and generate implementations for them just as you would for any other type:
e.g:
public class InstantiatorGenerator extends Generator {
public String generate(...) {
TypeOracle typeOracle = context.getTypeOracle();
JClassType myTYpe= typeOracle.findType(MyInterface.class.getName());
JClassType[] types = typeOracle.getTypes();
List<JClassType> myInterfaceTypes = Collections.createArrayList();
// Collect all my interface types.
for (JClassType type : types) {
if (type.isInterface() != null && type.isAssignableTo(myType)
&& type.equals(myType) == false) {
myInterfaceTypes.add(type);
}
for (JClassType nestedType : type.getNestedTypes()) {
if (nestedType.isInterface() != null && nestedType.isAssignableTo(myType)
&& nestedType.equals(myTYpe) == false) {
myInterfaceTypes.add(nestedType);
}
}
}
for (JClassType jClassType : myInterfaceTypes) {
MyInterfaceGenerator generator = new MyInterfaceGenerator();
generator.generate(logger, context, jClassType.getQualifiedSourceName());
}
}
// Other instantiator generation code for if () else if () .. constructs as
// explained below.
}
The MyIntefaceGenerator class is just like any other deferred binding generator. Except you call it directly within the above generator instead of via GWT.create. Once the generation of all known sub-types of MyInterface is done (when generating sub-types of MyInterface in the generator, make sure to make the classname have a unique pattern, such as MyInterface.class.getName() + "_MySpecialImpl"), simply create the Instantiator by again iterating through all known subtypes of MyInterface and creating a bunch of
if (clz.getName().equals(MySpecialDerivativeOfMyInterface)) { return (T) new MySpecialDerivativeOfMyInterface_MySpecialImpl();}
style of code. Lastly throw an exception so you can return a value in all cases.
Now where you'd call GWT.create(clz); instead do the following:
private static final Instantiator instantiator = GWT.create(Instantiator.class);
...
return instantiator.create(clz);
Also note that in your GWT module xml, you'll only define a generator for Instantiator, not for MyInterface generators:
<generate-with class="package.rebind.InstantiatorGenerator">
<when-type-assignable class="package.impl.Instantiator" />
</generate-with>
Bingo!
What exactly is the question - i am guessing you wish to pass parameters in addition to the class literal to a generator.
As you probably already know the class literal passed to GWT.create() is mostly a selector so that GWT can pick and execute a generator which in the end spits out a class. The easist way to pass a parameter to the generator is to use annotations in an interface and pass the interface.class to GWT.create(). Note of course the interface/class must extend the class literal passed into GWT.create().
class Selector{
}
#Annotation("string parameter...")
class WithParameter extends Selector{}
Selector instance = GWT.create( WithParameter.class )
Everything is possible..although may be difficult or even useless. As Jan has mentioned you should use a generator to do that. Basically you can create your interface the generator code which takes that interface and compile at creation time and gives you back the instance. An example could be:
//A marker interface
public interface Instantiable {
}
//What you will put in GWT.create
public interface ReflectionService {
public Instantiable newInstance(String className);
}
//gwt.xml, basically when GWT.create finds reflectionservice, use reflection generator
<generate-with class="...ReflectionGenerator" >
<when-type-assignable class="...ReflectionService" />
</generate-with>
//In not a client package
public class ReflectionGenerator extends Generator{
...
}
//A class you may instantiate
public class foo implements Instantiable{
}
//And in this way
ReflectionService service = GWT.create(ReflectionService.class);
service.newInstance("foo");
All you need to know is how to do the generator. I may tell you that at the end what you do in the generator is to create Java code in this fashion:
if ("clase1".equals(className)) return new clase1();
else if ("clase2".equals(className)) return new clase2();
...
At the final I thought, common I can do that by hand in a kind of InstanceFactory...
Best Regards
I was able to do what I think you're trying to do which is load a class and bind it to an event dynamically; I used a Generator to dynamically link the class to the event. I don't recommend it but here's an example if it helps:
http://francisshanahan.com/index.php/2010/a-simple-gwt-generator-example/
Not having looked through the code of rocket/gwittir (which you ought to do if you want to find out how they did it, it is opensource after all), i can only guess that they employ deferred binding in such a way that during compile time, they work out all calls to reflection, and statically generate all the code required to implement those call. So during run-time, you cant do different ones.
What you're trying to do is not possible in GWT.
While GWT does a good job of emulating Java at compile time the runtime is of course completely different. Most reflection is unsupported and it is not possible to generate or dynamically load classes at runtime.
I had a brief look into code for Gwittir and I think they are doing their "reflection stuff" at compile time. Here: http://code.google.com/p/gwittir/source/browse/trunk/gwittir-core/src/main/java/com/totsp/gwittir/rebind/beans/IntrospectorGenerator.java
You might be able to avoid the whole issue by doing it on the server side. Say with a service
witch takes String and returns some sort of a serializable super type.
On the server side you can do
return (MySerializableType)Class.forName("className").newInstance();
Depending on your circumstances it might not be a big performance bottleneck.