I'm trying to make implementations of new versions of a 3rd party WebService easier and simple.
For that I've change all WSDL generated classes to Interfaces with the same methods and properties.
Changed the service interface to a Generic one
And made a AbstractFactory to create the real products deppending on each version.
When all that was done, after solving other minor errors, I ran my tests I got:
First chance exception at $75E5C42D. Exception class ERemotableException with message 'Cannot find dispatch method for {}consultarAlteracao'. Process intWSServidor.exe (7364)
There was a class consultarAlteracao and it becomes IconsultarAlteracao.
I've tried to change the InvRegistry and all other methods to use the interface and abstract classes, but no success on it.
That ends up in Delphi does not supports interfaced elements as properies for TRemotable objects.
After change all properties to abstract classes that implements the basic interface everithing worked out fine
Related
There is an emphasis on using interfaces instead of concrete types in order to make the code easier to test. I wonder though why this wasn't done for the types in the sql package like DB or Rows. In order to mock those dependencies I had to create my own interfaces so that I could write unit tests (not integration tests). Aren't DB facing code supposed to be tested that way?
Exposing interfaces in your public API instead of concrete types increases the risk of breaking other peoples code when you add methods to the interface.
See for example os.File. If os.File was an interface it would be an interface with 17 public methods. Adding an 18th method would break everyone who defined their own types that implemented the os.File interface. In contrast, adding an 18th method to the current os.File struct won't break any methods taking an io.Reader, io.Writer or any other interface that defines a subset of the methods of an os.File. It also won't break test code which mocks these io.Reader and io.Writer interfaces.
So expose an interface in your public API if you want other people to define their own implementations of them. Otherwise expose a concrete type and let people define their own interfaces implemented by your concrete type using only the subset of methods they need.
I have added a new interface IAEx which is extended from the existing interface IA (derived from IDispatch).
What are the things to change in idl?
I have changed the coclass definitions to inherit from the new one.
I changed the coclass entry in idl which was like this earlier.
(I need the deafult interface as new one)
coclass CAx
{
[default] interface IA
[default, source] dispinterface IAEvents;
};
and changed to
coclass CAx
{
[default] interface IAEx
[default, source] dispinterface IAEvents;
};
can I change the deafualt interafce?
coclass definition change.
old one
class ATL_NO_VTABLE CAx:
...
public CCIDispatchImpl<IA, &IID_IA, &LIBID_CCALib>,
new one.
class ATL_NO_VTABLE CAx:
...
public CCIDispatchImpl<IAEx, &IID_IAEx, &LIBID_CCALib>,
Is this fine?
COM MAP entries modification:
Old one:
COM_INTERFACE_ENTRY(IA)
COM_INTERFACE_ENTRY2(IDispatch,IA)
new one:
COM_INTERFACE_ENTRY(IAEx)
COM_INTERFACE_ENTRY2(IDispatch,IAEx)
Do I need to add old interface also in COM MAP?
No, this is a drastically breaking change to client programs. Golden rule #1 to keep in mind is that names are quite immaterial in COM, only uuids matter. Rule #2 is that COM components have machine scope, modifying a component affects every program on the machine that uses the component. Another way to say that is that COM has a strong DLL Hell problem.
So the first thing that will happens when you install your component on a machine is that every program that uses it will stop to work. They are still looking for the "IA" interface uuid and it is not there anymore. They fail with E_NOINTERFACE. Only way to avoid that is to get the client programs recompiled with your new type library and deploy them at the exact same time your updated COM component is deployed. This is often very hard to arrange since they don't have programmers or companies in common. Usually only the user can do this, they very rarely know how to do this correctly or know how to troubleshoot failure.
If you want your update to be backwards compatible then you must add a new interface to your coclass. It cannot be the [default] interface since existing client programs expect the legacy interface as the default. That however causes a new problem, client runtimes that use IDispatch often don't support anything but a single default interface. Usually because they don't have a notion of interfaces as a primary language construct. In other words, your client programmer has no way to call IUnknown::QueryInterface() and therefore cannot use your new interface at all. So not a general solution.
It is technically possible to violate the interfaces are immutable rule in COM. You can add new methods to the end of the IDispatch interface. Existing client code is unaware of them so will never call them and continue to operate correctly both with the old and the new version of your component. Assuming that you know how to maintain the legacy methods without causing a breaking behavior change, often harder than it looks. There is still a DLL Hell problem though, the world implodes when an updated version of the client code meets the old version of your component. This might seem unlikely at first sight but this tends to go wrong much later, when the machine is replaced or re-imaged. Very ugly scenario, the runtime failure is impossible to diagnose and anybody originally involved is not around anymore or doesn't remember the details.
Only truly safe way to do this is to create a new version. Modify all the uuids (LIBID, CLSID and IID) and change the DLL filename. Now the old and new version can co-exist and the client programmer can use your new version at his leisure. There might still be a deployment problem but the failure is easy to diagnose, the client program fails with "Class not registered".
You should include the old interface in the COM MAP as well as if a client attempts to QueryInterface for the old interface it should receive a useful result and not an error. Add COM_INTERFACE_ENTRY2(IA, IAEx).
Otherwise it looks like you have everything. We add both interfaces into the coclass entry in the IDL file but I don't thing anything really uses that. ie:
coclass Ax
{
[default] interface IAEx;
interface IA;
};
Whether it is fine or not depends on what is the goal exactly. Replacing interface is fine on its own, if you are concerned with not breaking compatibility with existing client, the most important thing is that your server still implements old interface IA. You should list the interface on the COM MAP (since you mentioned that IAEx is inherited from IA, you might need a COM_INTERFACE_ENTRY_IID macro):
COM_INTERFACE_ENTRY(IAEx)
COM_INTERFACE_ENTRY_IID(__uuidof(IA), IAEx) //COM_INTERFACE_ENTRY(IA)
COM_INTERFACE_ENTRY2(IDispatch, IAEx)
This way your server implements both IAEx and IA. Inheriting interfaces one from another is the thing I would rather suggest against, but you have what you have.
Updating coclass (as suggested in answer by patthoyts) makes update cleaner and is worth doing as well, however it is more important for rebuilding the clients rather than keeping compatibility with already existing built code: tools importing type library information will be able to see both interfaces if they at all care and are capable to handle non-default interfaces there.
i have a legacy COM components, as part of upgradation i derived from an existing interface
interface1
{
few methods
}
interface2 :public interface1
{
new methods
}
there was an old review comment not to do this..instead have inteface2 has separate one not deriving from the base, as it part of the same CoClass...there is no need to duplicate any code...
review comment :
Scripting languages are interpreted languages and are naturally polymorphic as all methods are late bound. All variables are typeless (VARIANT is typeless).
However, there is a separate problem concerning scripting languages. Scripting languages do not use the virtual function table in order to invoke methods on a COM object but instead invoke methods via the IDispatch interface. Unfortunately IDispatch can only be associated with one custom interface.
All methods accessed via IDispatch must be part of the custom interface
can anyone explain ...does he mean to say that getidsofnames will not be able to return the correct ID ? or is it something else
It is accurate enough, a coclass can implement multiple interfaces. But one is "special", it is the one that's attributed with [default] in the IDL. Scripting languages can only use that default interface, they don't have a mechanism to retrieve another interface. Or in other words, they can't call QueryInterface(). Mostly because they don't support the notion of interfaces or casting or multiple inheritance at all in their language design. Intentionally, scripting languages are supposed to be easy to use.
So if interface1 was originally the default interface then the scripting programmer can never use the added interface2 methods. You'll want to have a look at this SO post to see the consequences.
You can keep COM interfaces backwards compatible with old client programs by only ever appending new methods and never change the order or arguments of the old ones. It is risky, an updated client program that accidentally meets an old version of your component will go up in flames in a very bad way. Usually very hard to diagnose, pure DLL Hell. Only truly safe way is to assign new [uuid]s, forcing the client program to be recompiled. If you also change the name or install location of the DLL then they can live side-by-side.
I am using the Poco generator with EF4 and I am wondering if it is possible to edit the T4 template to force all of my entity classes to implement a custom interface. Since the pocos get blown away and recreated each time the custom tool is run, I would have to add this upon each update - I would sure like to avoid that.
I realize I could create partial classes for each poco and implement the interface there, but I was hoping to avoid all that boilerplate code.
Any suggestions would be welcome.
I think I am getting closer to a solution. I am editing the tt template by adding the implemenatation to the signature that is generated.
<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#> : IEntity<#=code.StringBefore(" , ", code.Escape(entity.BaseType))#>
But I have hit a bit of a snag. Some of my entities have base classes (table inheritance) that I designated in the edmx design. I have need to force all the entities to implement an interface called IEntity. The IEntity contract has no methods so there really is nothing to implement. I will need to rely on all of the entities having a common base. This is due to a completely separate implementation of a custom validation framework. I am getting the proper signatures for most of the entities, however, the entities that already have a base class are throwing a wobbly because you cant implement an interface before you inherit a base class. :IEntity, BaseClass is not allowed. I need to swap those but am not sure how I would pull that off in the template.
On perusing the code in the CodeGenerationTools class that the T4 template uses (found in the include file EF.Utility.CS.ttinclude), I came across this function StringAfter(string value, string append). Therefore, the answer is quite simple, since you state all your entities have to implement IEntity, the following should do the trick:
<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#> : <#=code.StringAfter(code.Escape(entity.BaseType), "," )#> IEntity
In fact, I know it does because I've tested it :-)
After the T4 template is added to your application, it becomes part of your app and as any other part of the app, you can do whatever you want with it. If for some reason, you don't want to modify the VS added template, make a copy of it and update this to include only the interface implementation. The second way would produce another set of partial files with the custom interface being implemented.
Dont know if this is near what you need but....
I´ve created a Nuget Package that scaffold tiers from T4-templates.
There are default templates for all interfaces (Repository Pattern and UnitOfWork), but you can edit these templates yourself and re-scaffold your system.
To keep it short.. You just install the package (Install-Package CodePlanner) and then define your domainmodel.. And then run "Scaffold CodePlanner.ScaffoldAll"
Its open source (codeplanner.codeplex.com)
Demo: http://average-uffe.blogspot.com/2011/11/codeplanner-011-released-on-nuget-and.html
Edit: The codeplanner package is built for MVC3!
Regards
Uffe
I have a code base where many of the classes I implement derive from classes that are provided by other divisions of my company. Working with these other devisions often have the working relationship as though they are third party middle ware vendors.
I'm trying to write test code without modifying these base classes. However, there are issues with creating meaningful test
objects due to the lack of interfaces:
//ACommonClass.h
#include "globalthermonuclearwar.h" //which contains deep #include dependencies...
#include "tictactoe.h" //...and need to exist at compile time to get into test...
class Something //which may or may not inherit from another class similar to this...
{
public:
virtual void fxn1(void); //which often calls into many other classes, similar to this
//...
int data1; //will be the only thing I can test against, but is often meaningless without fxn1 implemented
//...
};
I'd normally extract an interface and work from there, but as these are "Third Party", I can't commit these changes.
Currently, I've created a separate file that holds fake implementations for functions that are defined in the third-party supplied base class headers on a need to know basis, as has been described in the book "Working with Legacy Code".
My plan was to continue to use these definitions and provide alternative test implementations for each third party class that I needed:
//SomethingRequiredImplementations.cpp
#include "ACommonClass.h"
void CGlobalThermoNuclearWar::Simulate(void) {}; // fake this and all other required functions...
// fake implementations for otherwise undefined functions in globalthermonuclearwar.h's #include files...
void Something::fxn1(void) { data1 = blah(); } //test specific functionality.
But before I start doing that I was wondering if any one has tried providing actual objects on a code base similar to mine, which would allow creating new test specific classes to use in place of actual third-party classes.
Note all code bases in question are written in C++.
Mock objects are suitable for this kind of task. They allow you to simulate the existence of other components without needing them to be present. You simply define the expected input and output in your tests.
Google have a good mocking framework for C++.
I'm running into a very similar problem at the moment. I don't want to add a bunch of interfaces that are only there for the purpose of testing, so I can't use any of the existing mock object libraries. To get around this I do the same thing, creating a different file with fake implementations, and having my tests link the fake behaviour, and production code links the real behaviour.
What I wish I could do at this point, is take the internals of another mock framework, and use it inside my fake objects. It would look a little something like this:
Production.h
class ConcreteProductionClass { // regular everyday class
protected:
ConcreteProductionClass(); // I've found the 0 arg constructor useful
public:
void regularFunction(); // regular function that I want to mock
}
Mock.h
class MockProductionClass
: public ConcreteProductionClass
, public ClassThatLetsMeSetExpectations
{
friend class ConcreteProductionClass;
MockTypes membersNeededToSetExpectations;
public:
MockClass() : ConcreteProductionClass() {}
}
ConcreteProductionClass::regularFunction() {
membersNeededToSetExpectations.PassOrFailTheTest();
}
ProductionCode.cpp
void doSomething(ConcreteProductionClass c) {
c.regularFunction();
}
Test.cpp
TEST(myTest) {
MockProductionClass m;
m.SetExpectationsAndReturnValues();
doSomething(m);
ASSERT(m.verify());
}
The most painful part of all this is that the other mock frameworks are so close to this, but don't do it exactly, and the macros are so convoluted that it's not trivial to adapt them. I've begun looking into this on my spare time, but it's not moving along very quickly. Even if I got my method working the way I want, and had the expectation setting code in place, this method still has a couple drawbacks, one of them being that your build commands can get to be kind of long if you have to link against a lot of .o files rather than one .a, but that's manageable. It's also impossible to fall through to the default implementation, since we're not linking it. Anyway, I know this doesn't answer the question, or really even tell you anything you don't already know, but it shows how close the C++ community is to being able to mock classes that don't have a pure virtual interface.
You might want to consider mocking instead of faking as a potential solution. In some cases you may need to write wrapper classes that are mockable if the original classes aren't. I've done this with framework classes in C#/.Net, but not C++ so YMMV.
If I have a class that I need under test that derives from something I can't (or don't want to) run under test I'll:
Make a new logic-only class.
Move the code-i-wanna-test to the logic class.
Use an interface to talk back to the real class to interact with the base class and/or things I can't or won't put in the logic.
Define a test class using that same interface. This test class could have nothing but noops or fancy code that simulates the real classes.
If I have a class that I just need to use in testing, but using the real class is a problem (dependencies or unwanted behaviors):
I'll define a new interface that looks like all of the public methods I need to call.
I'll create a mock version of the object that supports that interface for testing.
I'll create another class that is constructed with a "real" version of that class. It also supports that interface. All interface calls a forwarded to the real object methods.
I'll only do this for methods I actually call - not ALL the public methods. I'll add to these classes as I write more tests.
For example, I wrap MFC's GDI classes like this to test Windows GDI drawing code. Templates can make some of this easier - but we often end up not doing that for various technical reasons (stuff with Windows DLL class exporting...).
I'm sure all this is in Feather's Working with Legacy Code book - and what I'm describing has actual terms. Just don't make me pull the book off the shelf...
One thing you did not indicate in your question is the reason why your classes derive from base classes from the other division. Is the relationship really a IS-A relationshiop ?
Unless your classes needs to be used by a framework, you could consider favoring delegation over inheritance. Then you can use dependency injection to provide your class with a mock of their class in the unit tests.
Otherwise, an idea would be to write a script to extract and create the interface your need from the header they provide, and integrate this to the compilation process so your unit test can ve checked in.