ExcelDna - Excel can't access function in base class - excel-dna

When Excel tries to call a method in a abstract base class i get a Run-Time error
"Cannot run Marco 'MarcoName'. The macro may not be available"
I can run code from the super class.
The code is similar to this
public abstract class MyBaseClass
{
public static bool MyMethod(string path)
{
if(Valid(path))
{return true;}
return false;
}
}
This code is in a separate assembly imported via a nuget package
The calling code is similar to the below
public class MyClass : MyBaseClass
{
public static bool MyOtherMethod()
{
return true;
}
}
Marking the methods with the "[ExcelFunction]" attribute has no effect.
I am loading the xll file like so,
Application.RegisterXLL (path)
I call the method like so,
Application.Run("MyMethod", path)

Only code in assemblies that are included in the <ExternalLibrary ... /> list in the .dna file are scanned for functions to register. Maybe your external assembly is not mentioned there.
Also, abstract types were not always considered. It looks like this changed at some point, if I look at the code that scans the assemblies here: https://github.com/Excel-DNA/ExcelDna/blob/57c2d0a499a044f6cd1c4ae2c9fbf5b084159dea/Source/ExcelDna.Integration/AssemblyLoader.cs#L93
So it might depend on your Excel-DNA version too.
Easiest might be to have a class with all the functions you want to export, where you can add the Excel-specific attributes (<ExcelFunction .../>) and just forward the calls internally.

Related

Does Processing 3 have class declarations?

Our school project has us make a game using Processing 3. After some studying with the language, our team is pretty confident we can work with the project, though we do have certain reservations of the chosen language.
However, there is one major question we are wondering and could not find an answer. In C++ and many others, when you create a new class in a new file you also create a header file you can include. Does Processing 3 have something similar? I know you can "include" files by adding more tabs, which is still weird but whatever. We would like to have some sort of declarations in advance so we can comment/describe classes and their methods, rather than force each member go through lots of code to find the proper point.
In short, we want to be able to do something like this:
Example.pde
class Example {
//Description
Example();
//Description
void doSomething(int variable);
}
//Other team members don't have to worry past this,
//as they have already seen the public interface
Example::Example()
{
//Constructor
}
void Example::doSomething(int variable)
{
//Function
}
Or do we have to always to like this:
Example.pde
class Example {
//Description
Example()
{
//Constructor
}
//Description
void doSomething(int variable)
{
//Function
}
}
Processing is written in Java, so you can only do things that Java supports. Java does not support header files, so no, you can't use header files in Processing.
However, it sounds like what you're really looking for is an interface.
interface Example {
void doSomething(int variable);
}
class MyExample implements Example{
public MyExample(){
//Constructor
}
void doSomething(int variable){
//Function
}
}
With this, you would only need to show other team members the interface, not the class. As long as they program to the interface, they don't need to ever see the class implementation.
More info on interfaces can be found in the Processing reference.

MVVMCross - Navigate ViewModel

When I try to open a new viewmodel I'm receiving the following error:
Failed to load ViewModel for type EasyBudget.Core.ViewModels.GridCategoryViewModel from locator MvxDefaultViewModelLocator
It´s also shows:
No symbols found.
And shows that cannot find or open the PDB file.
My viewmodel:
public class HomeViewModel
: MvxViewModel
{
private Cirrious.MvvmCross.ViewModels.MvxCommand _listCommandCategory;
public System.Windows.Input.ICommand ListCommandCategory
{
get
{
_listCommandCategory = _listCommandCategory ?? new Cirrious.MvvmCross.ViewModels.MvxCommand(DoListCategory);
return _listCommandCategory;
}
}
private void DoListCategory()
{
ShowViewModel<GridCategoryViewModel>();
}
}
And my other viewmodel:
public partial class GridCategoryView : MvxPhonePage
{
public GridCategoryView()
{
InitializeComponent();
}
}
Does anyone knows what may I be forgeting?
Best regards
Wilton Ruffato Wonrath
I believe the problem will most likely be somewhere in the construction of the ViewModel:
perhaps the constructor itself isn't public?
perhaps one or more of the parameters for the constructor couldn't be found?
perhaps some code inside the constructor has thrown an exception
Where you posted 'my other viewmodel' you actually posted code only for your other view. Can you post the code for the ViewModel that accompanies that view?
If you enable your debugger to break on all Exceptions, then this will possibly help you to find the problem that occurs during loading (inside https://github.com/slodge/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross/ViewModels/MvxDefaultViewModelLocator.cs).
If you want to a pdb for debugger symbols, then these can be found inside the folders of http://github.com/slodge/MvvmCross-Binaries - inside the VS2012/Release folders. We are also currently trying to work out how to distribute these via SymbolSource.org (first got the request/suggestion this week)
Finally, if you want to see trace from a Windows build and are using the release packages from nuget then you can do this by overriding CreateDebugTrace() in your Setup.cs file - e.g. try:
protected override IMvxTrace CreateDebugTrace()
{
return new MvxDebugTrace();
}
This will also allow you to add some debug trace to your Core code if you want to using:
Mvx.Trace(format, args...)
Mvx.Warning(format, args...)
Mvx.Error(format, args...)
Perhaps, you forgot about adding ViewModel type to your generic MvxPhonePage.
Try this:
public partial class GridCategoryView : MvxPhonePage<GridCategoryViewModel>

Selenium RC User Defined Functions

Trying to do something simple -
I have a set of statements to clear browser cookies:
public void clearCookies () {
selenium.open("http://www.myurl.com");
selenium.waitForPageToLoad("10000");
selenium.deleteAllVisibleCookies();
}
Now, if I use this function in a test script (using TestNG), calls to this work perfectly. However, if I moved this function to a separate class and change the declaration to include "static", the "selenium" keyword is not recognized.
In a configuration class (say configClass),
public static void clearCookies () {
selenium.open("http://www.myurl.com");
selenium.waitForPageToLoad("30000");
selenium.deleteAllVisibleCookies();
}
Now, in my test script, if I call configClass.clearCookies();, I get a runtime error
I tried declaring DefaultSelenium selenium = new DefaultSelenium(null);, in the clearCookies() function, but that too results in a runtime error.
I do have the import com.thoughtworks.selenium.*; import in my configClass.
Any pointers would be appreciated. Thanks.
You can do two things.
Refer to the same selenium object in both the classes i.e. in configClass and the class you are calling configClass.clearCookies().
or else
send selenium object to the clearCookies. So the code would be like this
public static void clearCookies (DefaultSelenium selenium) {
selenium.open("http://www.myurl.com");
selenium.waitForPageToLoad("30000");
selenium.deleteAllVisibleCookies();
}

Customizing MEF

I have this situation where I want to use MEF in a chess project I'm workin on. Let's say I have a class constructor as in:
public class MoveManager
{
private Piece _piece;
public MoveManager(Piece piece)
{
_piece = piece;
}
Mode code here...
}
In this context I would have several classes that would derive from Piece like, Pawn, Rook, etc. If I put export attributes on all the classes the derive from Piece, the object being passed into the constructor is null. MEF loops through all classes the have the [Export(typeof(Piece))] and if it exceeds 1, it passes in null. So I cannot use MEF in this way. I'm going to use an Abstact Factory for getting the correct piece. Seems like the DI part of MEF can only take a single class that has the [Export(typeof(some base class))].
Can anyone shed some light on this?
I think you might be looking for the [Importing Constructor] arrtibute, which tells MEF how to use an exported class's constructor.
[Export(typeof(IPiece))]
class Pawn : IPiece
{
[ImportingConstructor]
public Pawn(ISomeDependency dep, [ImportMany] IEnumerable<IOtherDependency> depList)
{
//... do stuff with dependencies
}
}
This requires that an ISomeDependency is exported elsewhere (exactly once) and accepts any number of IOtherDependency's that might be exported too.
Supposing you did this with each piece, you could then:
[Export(typeof(IPieceList))]
class PieceList : IPieceList
{
[ImportingConstructor]
public PieceList([ImportMany] IEnumerable<IPiece> pieces)
{
// pieces now contains one of each piece that was exported above
}
}

Enterprise Library Validation Block - Should validation be placed on class or interface?

I am not sure where the best place to put validation (using the Enterprise Library Validation Block) is? Should it be on the class or on the interface?
Things that may effect it
Validation rules would not be changed in classes which inherit from the interface.
Validation rules would not be changed in classes which inherit from the class.
Inheritance will occur from the class in most cases - I suspect some fringe cases to inherit from the interface (but I would try and avoid it).
The interface main use is for DI which will be done with the Unity block.
The way you are trying to use the Validation Block with DI, I dont think its a problem if you set the attributes at interface level. Also, I dont think it should create problems in the inheritance chain. However, I have mostly seen this block used at class level, with an intent to keep interfaces not over specify things. IMO i dont see a big threat in doing this.
Be very careful here, your test is too simple.
This will not work as you expect for SelfValidation Validators or Class Validators, only for the simple property validators like you have there.
Also, if you are using the PropertyProxyValidator in an ASP.NET page, iI don;t believe it will work either, because it only looks a field validators, not inherited/implemented validators...
Yes big holes in the VAB if you ask me..
For the sake of completeness I decided to write a small test to make sure it would work as expected and it does, I'm just posting it here in case anyone else wants it in future.
using System;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ISpike spike = new Spike();
spike.Name = "A really long name that will fail.";
ValidationResults r = Validation.Validate<ISpike>(spike);
if (!r.IsValid)
{
throw new InvalidOperationException("Validation error found.");
}
}
}
public class Spike : ConsoleApplication1.ISpike
{
public string Name { get; set; }
}
interface ISpike
{
[StringLengthValidator(2, 5)]
string Name { get; set; }
}
}
What version of Enterprise Library are you using for your code example? I tried it using Enterprise Library 5.0, but it didn't work.
I tracked it down to the following section of code w/in the EL5.0 source code:
[namespace Microsoft.Practices.EnterpriseLibrary.Validation]
[public static class Validation]
public static ValidationResults Validate<T>(T target, ValidationSpecificationSource source)
{
Type targetType = target != null ? target.GetType() : typeof(T);
Validator validator = ValidationFactory.CreateValidator(targetType, source);
return validator.Validate(target);
}
If the target object is defined, then target.GetType() will return the most specific class definition, NOT the interface definition.
My workaround is to replace your line:
ValidationResults r = Validation.Validate<ISpike>(spike);
With:
ValidationResults r ValidationFactory.CreateValidator<ISpike>().Validate(spike);
This got it working for me.

Resources