How come you can create an interface instance in Office Interop? - ms-word

I've seen this quite a few times while using Office Interop classes
this.CustomXMLParts.Add(MyResources.Data, new Office.CustomXMLSchemaCollection());
If I hover over the CustomXMLSchemaCollection class, it shows up as an interface. Then how come I can do a new on it ? What gives?
BTW this code compiles and works.

You are not creating an instance of the CustomXMLSchemaCollection interface but an instance of the CustomXMLSchemaCollectionClass coclass.
The definition for CustomXMLSchemaCollection interface is:
[Guid("000CDB02-0000-0000-C000-000000000046")]
[CoClass(typeof(CustomXMLSchemaCollectionClass))]
public interface CustomXMLSchemaCollection : _CustomXMLSchemaCollection
{
}
This means that the designated coclass that implements the interface is CustomXMLSchemaCollectionClass. My guess is that when the C# compiler sees the new for CustomXMLSchemaCollection interface it translates it to create a COM instance of the CustomXMLSchemaCollectionClass based on the attributes provided with the interface.
After writing this simple example:
namespace ConsoleApplication2
{
using System;
using Office = Microsoft.Office.Core;
class Program
{
static void Main(string[] args)
{
Office.CustomXMLSchemaCollection test = new Office.CustomXMLSchemaCollection();
}
}
}
I just ran ildasm and get the following MSIL:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 8 (0x8)
.maxstack 1
.locals init ([0] class [Interop.Microsoft.Office.Core]Microsoft.Office.Core.CustomXMLSchemaCollection test)
IL_0000: nop
IL_0001: newobj instance void [Interop.Microsoft.Office.Core]Microsoft.Office.Core.CustomXMLSchemaCollectionClass::.ctor()
IL_0006: stloc.0
IL_0007: ret
} // end of method Program::Main
As you can see the class that is constructed is CustomXMLSchemaCollectionClass to prove my initial assumption.

Related

Usage of JsniBundle: calling methods on initialized js library

When I initialize d3.js and dc.js using JsniBundle there is no global variable "dc" or "d3" that is created. But I initialze crossfilter in the same way and there is window.crossfilter present.
My question is: what is the best way to call methods from the dc library using JsniBundle? Is using JsUtils.prop(window, "dc") the correct way to get a reference to the library object?
In the method drawBarChartWidget() below, the variable "dc" is null.
public interface D3Bundle extends JsniBundle {
#LibrarySource("d3.js")
public void initD3();
}
public interface CrossfilterBundle extends JsniBundle {
#LibrarySource("crossfilter.js")
public abstract void initCrossfilter();
}
public abstract static class DCBundle implements JsniBundle {
#LibrarySource("dc.js")
public abstract void initDC();
public void drawBarChart(Widget container, JSONValue data, Properties chartConfig) {
JavaScriptObject dc = JsUtils.prop(window, "dc");
}
}
LayoutPanel layoutPanel = new LayoutPanel();
SimplePanel chartPanel = new SimplePanel();
public ChartDemo() {
D3Bundle d3 = GWT.create(D3Bundle.class);
CrossfilterBundle crossfilter = GWT.create(CrossfilterBundle.class);
final DCBundle dc = GWT.create(DCBundle.class);
d3.initD3();
crossfilter.initCrossfilter();
dc.initDC();
Maybe not a direct answer to your question, but if you want to use d3.js with GWT, there is a wrapper that cover most of the main APIs from d3.js :
https://github.com/gwtd3/gwt-d3
Here's what made it work:
change final assignment statement in d3.js library from
this.d3 = d3;
to
window.d3 = d3;
and change final assignment statement in dc.js library from
this.dc = _dc(d3);
to
window.dc = _dc(window.d3);
I assume this is because of some weirdness around the iframe context that GWT code is executed in, but I'm not totally clear on why it works. I haven't done it yet but I believe that instead of editing the original library you can use the "replace" attribute of the LibrarySource annotation to automate that substitution.

Load a ListBox content dynamically on page load

I'm currently working on a simple GWT project. One of the things I'd like to do is that when the page loads I can dynamically populate the contents of a ListBox based on certain criteria. I actually don't see any handlers for a ListBox to handle the initial render event but I see change handlers.
How does one populate a ListBox contents with data from the server side on pageload with GWT?
Right now I have a class that implements EntryPoint that has a
final ListBox fooList = new ListBox();
I also have a set of beans but I also have a class implementing RemoteService. Since I can't seem to get direct calls to my user defined packages directly in the EntryPoint (which makes sense) how do I populate that ListBox with server side content on initial page load? Right now I'm using a List but I figure if I cant get that to work I can get a DB call to work...
I've tried things in the EntryPoint like:
for (String name : FOOS) {
fooList.addItem(name, name);
}
However FOOS would derive from a server side data and the EntryPoint is supposed to be largerly limited to what can compile to JS! I can't get user defined classes to be recognized on that side as that string is the result of a set of user defined classes.
I also tried creating a method in the class implementing RemoteService that returns a ListBox. This also didn't compile when I tried to call this method. Perhaps I don't fully understand how to call methods in a RemoteService service implementing class.
I've searched a lot and I can't find anything that clearly explains the fundamentals on this. My background is much more ASP.NET and JSPs so perhaps I'm missing something.
I'm using GWT 2.6 is that is relevant.
The usual procedure is the following:
Create a bean class for the data you want to transmit between client and server. Let's call it MyBean.
Place MyBean in the shared package of your project.
This class has to implement either Serializable or IsSerializable, otherwise GWT will complain that it doesn't know how to transmit it.
Create your RemoteService that contains the method you want to use to transmit MyBean from/to the server.
Once you get your data on the client using an AsyncCallback and your RemoteService, fill the ListBox using your beans, e.g. by calling MyBean#getName() or MyBean#toString().
Success!
I based my example on the GWT sample project ( I named it example), just replace the classes and it should work :
public class Example implements EntryPoint {
/**
* Create a remote service proxy to talk to the server-side Greeting
* service.
*/
private final GreetingServiceAsync greetingService = GWT
.create(GreetingService.class);
/**
* This is the entry point method.
*/
public void onModuleLoad() {
final ListBox listBox = new ListBox();
RootPanel.get("sendButtonContainer").add(listBox);
greetingService.getSomeEntries(new AsyncCallback<String[]>() {
#Override
public void onSuccess(String[] result) {
for (int i = 0; i < result.length; i++) {
listBox.addItem(result[i]);
}
}
#Override
public void onFailure(Throwable caught) {
}
});
}
}
This is our EntryPoint, it creates a listbox and calls the server with a AsyncCallback to get some dynamic data. If the call is successfull (onSuccess), the data is written into the listbox.
The GreetingService interface define the synchronous methods, it is implemented in the GreetingServiceImpl class :
#RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
String[] getSomeEntries() ;
}
The asynchronous counterpart is the GreetingServiceAsync interface, we used it before to call the server :
public interface GreetingServiceAsync {
void getSomeEntries(AsyncCallback<String[]> callback) ;
}
The GreetingServiceImpl class is located on the server. Here you could call for example a database:
#SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
GreetingService {
#Override
public String[] getSomeEntries() {
String[] entries = { "Entry 1","Entry 2","Entry 3" };
return entries;
}
}
Now if you want to use some Bean/Pojo between the server and client, replace the String[] in each class/interface with the object name, put the class in the shared package and consider that it implements Serializable/IsSerializable.

MEF Composition .NET 4.0

Thanks in advance for your assistance. I have the following exported part:
[Export (typeof(INewComponent))] // orignally tried just [Export} here and importing NewComponent below
public class NewComponent : INewComponent
{
// does stuff including an import
}
The Console test program imports the above:
public class Program
{
[Import] // have tried variations on importing "NewComponent NewComponent" etc
public INewComponent NewComponent
{
get;
set;
}
public static void Main(string[] args)
{
var p = new Program();
var catalog = new AssemblyCatalog(typeof(Program).Assembly);
var container = new CompositionContainer(catalog);
container.ComposeParts(p);
}
The Composition fails with these CompositionExceptions (I removed the namespace to protect the guilty :)):
1) No valid exports were found that match the constraint
'((exportDefinition.ContractName == "INewComponent") AndAlso
(exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso
"INewComponent".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))',
invalid exports may have been rejected.
The Composition works successfully if I do the composition in the main program like this:
public class Program
{
public static void Main(string[] args)
{
INewComponent newComponent = new NewComponent();
var catalog = new AssemblyCatalog(typeof(Program).Assembly);
var container = new CompositionContainer(catalog);
container.ComposeParts(newComponent);
}
}
Thank You
Is your Exported part contained in the same Assembly as Program? If it is in a separate DLL, you need to include that Assembly in your catalog as well, like this:
var aggregateCatalog = new AggregateCatalog();
aggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
aggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(NewComponent).Assembly));
var container = new CompositionContainer(aggregateCatalog);
// etc...
If that's doesn't work, then there is a nice open source tool called Visual MEFx that can help you analyze your catalog. Here is a short article about setting it up:
Getting Started With Visual MEFx
In your NewComponent class you wrote this:
// does stuff including an import
If there is a problem with that unshown import, then MEF will complain about the Program.NewComponent import instead of the actual deeper cause. This is called "stable composition". Stable composition can be useful, but it also complicates the debugging of a failed composition.
You can follow the instructions in the MEF documentation about Diagnosing Composition Errors to home in on the actual cause.
In a small program, you can also try to call container.GetExportedValue<ISomeExport>() for a few exports until you find the one that is causing problems.

guice ignores providers?

It seems Guice is ignoring my #Provider methods of my module.
I have a class MyModule like this:
public class MyModule extends AbstractModule {
protected void configure() {
bindInterceptor(Matchers.any(), Matchers.annotatedWith(Timed.class), new GuiceEnabledLoggingInterceptor());
bind(OneClass.class).to(OneClassImpl.class);
// And more binding lines...
}
#Provides
public AnotherClassInApi provideMyClass() {
return AnotherClassInApi.getInstance();
}
// And more #Provides methods
}
Main method is
public static void main(String[] args){
ConfigHandler.getInstance().loadConfigWhenNotRunningInsideMicrocontainer();
Injector INJECTOR = Guice.createInjector(new MyModule());
// ...
}
In some other part of the project I have class AnotherClassInApi, which is a very standard singleton plus one method:
public class AnotherClassInApi {
private static final AnotherClassInApi INSTANCE = new AnotherClassInApi();
private AnotherClassInApi() { }
// ... more methods
public static AnotherClassInApi getInstance() {
return INSTANCE;
}
}
Well, I understand that should effectively bind any request for an AnotherClassInApi object to the getInstance() method, but it doesn't work. Funny thing, a breakpoint in the #Provide method is never reached while debugging, but one in the configure method is reached. It seems guice is ignoring my provider annotation, and I think I'm following exactly what Guice guide says about #Provider, so I'm already stuck.
I've been googling around, but can't find anything similar. Any help will be much appreciated.
Thanks!
The concept of Providers (and #Provides methods) is, that they are only called when actually needed. So unless you really use your Injector to create an instance that has an #Inject dependency, your Provider is not ignored, just not used (nor needed).
You can monitor all configured bindings by using "injector.getAllBindings()".
java.util.Map,Binding> getAllBindings()
Returns a snapshot
of this injector's bindings, both explicit and just-in-time. The
returned map is immutable; it contains only the bindings that were
present when getAllBindings() was invoked. Just-in-time bindings are
only present if they have been requested at least once. Subsequent
calls may return a map with additional just-in-time bindings. The
returned map does not include bindings inherited from a parent
injector, should one exist.
This method is part of the Guice SPI and is intended for use by tools
and extensions.

Java and main()

I'm messing around with Eclipse(and java in general) for the first time in about a year. among the things I have forgotten is the following:
I have a function (void callvote() that I am hoping will be activated by my main function (that is, automatically, relatively early in the program). I currently have it within the same class (body) as the main function itself.
I try to call it withcallvote(); and get an error, "- Cannot make a static reference to the non-static method callvote() from the type body"
my function callvote is, at the moment, in the space below main and simply says
public void callvote()
{
}
am i committing a horrible sin by putting more functions in the same class as main?
is this a relatively easy fix that I missed somehow?
What does this error mean?
Have I woken Azatoth with this code?
Thanks in advance,
Tormos
Without the static modifier callvote is implicitly an instance method - you need an instance of a class to call it.
You could mark it as static also:
public static void callvote() ...
Or create an instance of the declaring class:
MyClass instance = new MyClass();
instance.callvote();
main() is a static method, meaning you can call it directly from a class whereas non-static members can only be called from an object. In order for you to call the callvote() method you need to first instantiate an object of your class:
public static void main(String [ ] args) {
MyClass myObject = new MyClass();
myObject.callvote();
}
Another way to avoid the error is to make you callvote() method static as well, but it's usually not what you want to do (but it depends on the nature of your class and method).
This post describes some of the dangers with the overuse of static methods: Class with single method -- best approach?
Try this:
public class Main {
public static void main(String[] args) {
new Main().callvote()
}
}
the main() entry point of your java program is static. You cannot call a non static method from a static one.
So you have to instanciate your Class first and call the method after.