 |
| Pro VB 6 For advanced Visual Basic coders working in version 6 (not .NET). Beginning-level questions will be redirected to other forums, including Beginning VB 6. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the Pro VB 6 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

November 9th, 2006, 05:44 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 627
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
of course woody yours is a way to avoid dll hell (can't say how much I spent in hell already...) but sometimes that is not an options.
Our products have dozens of executables, servers, services, dll and ocx (the distribution cd has somethiing like 400 files, plus documentation). Using binary compatibility allow us to patch a customer problem just sending a new component, without having to release a new version of the software.
Not only that, but every developers can work on a separate project using the "old" version of all other components, without waiting for the otther guys to finish their work and to publish a new version of thei component.
But, that said , I hate how VB implements this compatibility issue... it works 99% of the times, and for the other 1% is hell!
|
|

November 9th, 2006, 06:49 PM
|
|
Friend of Wrox
|
|
Join Date: May 2006
Posts: 643
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
I agree, of course. There is no way to do patches to individual dlls unless you are using binary compatibility, with the exception of late binding, which allows you to ignore the guids. In our model, we do not do patches to individual dlls. However, a new release is made available about every 2 months.
One other thing: VB isn't so much to blame, so to speak, about how this compatibility works - it is a COM thing.
Woody Z http://www.learntoprogramnow.com
|
|

November 9th, 2006, 08:08 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 627
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
woody, our customers will kill us if they have to wait for two months :)
late binding is another good idea, but we are already concerned on speed and efficiency, I'd prefer to avoid it (besides that it cannot catch spelling mistakes or bad method syntax)
as for the the VB compatibilty, I wish there is an "advanced" mode. Sometimes we really want to break compatibility but keeping the same classID, because we know it is safe to do (the same way it is allowed for C++ projects)
|
|

November 13th, 2006, 01:01 PM
|
|
Friend of Wrox
|
|
Join Date: May 2006
Posts: 643
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Quote:
quote:Originally posted by marcostraf
woody, our customers will kill us if they have to wait for two months :)
|
Yes. Well, we also do "service releases", which can have as little as a 1 day turn-around. But our app is very stable, and most of our fixes are for obscure issues, so it is very infrequent that a "show-stopper" issue is discovered.
Quote:
quote:
late binding is another good idea, but we are already concerned on speed and efficiency, I'd prefer to avoid it (besides that it cannot catch spelling mistakes or bad method syntax)
|
There is a way to maintain your performance, as well as retain the syntax checking and intellisense while not needing to have a reference to the dll that contains your code. This is by using interfaces, and implementing the interface in the class your application will use. I don't see this often in VB6 projects, but I use it extensively. It isn't exactly "late binding" as most of us think of it - but it allows you to create your objects via a factory, and therefore your client app has no direct reference to the dll that contains the implementation. It only needs to reference the dll where the interface is defined. The only true late binding (if you use late binding at all in this scenario) will be with the Factory dll. Using this methodology, the only dll that needs to have binary compatibility selected is the one where the interfaces are defined - and as long as your interfaces are stable, you won't need to redeploy these often if at all. I have found this to be a very strong model.
Quote:
quote:
as for the the VB compatibilty, I wish there is an "advanced" mode. Sometimes we really want to break compatibility but keeping the same classID, because we know it is safe to do (the same way it is allowed for C++ projects)
|
Ahhh. That is Project Compatibility - the second choice in the Version Compatibility frame of the Component tab of the Project Properties dialog. However - no client will run against the code - you'll get the 429 error unless you recompile and deploy the clients.
Woody Z http://www.learntoprogramnow.com
|
|

November 13th, 2006, 02:51 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 627
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
this is for the original poster:
Brian, Woody and I had a lot of fun exchanging ideas on the version compatibility issue, I bet by now you are already bored (if not completely buffled). Maybe it is better to take a step back and come back to you: did you resolve your problem?
woody, the intarface dll fixes the syntax checking problem, but adds another layer and it is still late binding: IMHO the price to pay it is not worth the benefits.
I did not mean Project Compatibility, that as you stated correctly bumps bumps up the project versioning and will never run outside the IDE. Project compatibility (the default) is useful only during the design of the component, but as soon as the binary is compiled, the IDE should switch to Binary Compatibility automatically. It already happened that I forgot to do so, and I had to make a trip to hell (at least know I know the road :) ).
|
|

November 13th, 2006, 03:38 PM
|
|
Friend of Wrox
|
|
Join Date: May 2006
Posts: 643
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Quote:
quote:Originally posted by marcostraf
this is for the original poster:
Brian, Woody and I had a lot of fun exchanging ideas on the version compatibility issue, I bet by now you are already bored (if not completely buffled). Maybe it is better to take a step back and come back to you: did you resolve your problem?
|
I thought Brian was the original poster?
Quote:
quote:
woody, the intarface dll fixes the syntax checking problem, but adds another layer and it is still late binding: IMHO the price to pay it is not worth the benefits.
|
Well, it is NOT late binding: The interface provides direct VTable binding. And it doesn't add a layer as such, but rather provides a mechanism for writing decoupled code. [think plugins, metadata driven workflow, highly customizable functionality, etc]. Note that all your classes in your dlls already have interfaces, whether you define them yourself or not. By intentionally providing interfaces you get some of the benefits of modern OOP. For exmple, it provides a way to apply the the principle of polymorphism in a very decoupled manner, and more importantly (to me) is the ability to apply the Dependency Inversion principle (as per Robert Martin). If I couldn't do these things, I would find VB6 to very limiting.
Quote:
|
quote:I did not mean Project Compatibility, that as you stated correctly bumps up the project versioning and will never run outside the IDE. Project compatibility (the default) is useful only during the design of the component, but as soon as the binary is compiled, the IDE should switch to Binary Compatibility automatically. It already happened that I forgot to do so, and I had to make a trip to hell (at least know I know the road :) ).
|
Well, compiling to project compatibility doesn't interfere with using the objects developed outside of the IDE. However, depending on the end use of your compiled code, project compatibility is not useable when you are deploying the dll but not the recompiled clients that depend on the dll - that, of course, is what binary compatibility is for. In my case, I have several large projects that use project compatibility - and of course, as stated in an earlier post, we require that the old verison is uninstalled prior to installing the latest version since ALL the new (changed or not) dlls as well as clients will be installed.
Woody Z http://www.learntoprogramnow.com
|
|

November 13th, 2006, 06:24 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 627
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
sorry woody, I misinterpreted your post about the class Factory (this is why I talked about another "layer"). can you clarify a little bit the concept?
I understood that you have a client and a library, than you have an (extra?) library that defines the interface, and the first library implements the interface. Am I correct? How does that work?
|
|

November 13th, 2006, 08:19 PM
|
|
Friend of Wrox
|
|
Join Date: May 2006
Posts: 643
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Yes. You have the basic idea - but I am resistant to calling this "another layer".
Typically in this model, you have a library dll that defines the interface. This allows you to apply principles such as the Dependency Inversion priciple and the Interface Segregation priciple. This dll can contain as many interfaces as you want, as long as they relate to each other and follow the packaging principles, such as Release Reuse Equivalancy, Common Closure, Common Reuse, etc. Of course, in a large project you will probably have a number of dlls whose main function is to supply the interfaces that the rest of the application uses. These libraries can have references to other interface libraries, and even other typical class dlls when appropriate.
You also will have dlls that contain classes that provide the actual functionality - or the implementation - of the interfaces. Of critical importance here is that more than one class can implement the same interface, and this is a big part of the power of interfaces. It allows you to operate on objects without being aware of what the objects are - for example, in my projects, if an IReport interface is available on an object I know that I can use the IReport methods to run a report and that I can pass that object to a standard IOutput interface enabled object (such as RTF, or HTML, or whatever object) and expect to get back the formatted report - whatever it might be. Make sense? These dlls need to have references to the interface dlls, of course, and each class that implements an interface does so using the "Implements" keyword and supplies implementations of all the methods defined in the interface.(Note: In this case IReport and IOutput are interfaces I have defined for the purpose of doing reports and outputing them).
Next, I usually have a Factory dll (or more typically, a number of factory dlls) that can "hand out" objects based on the requirements of the requesting client. The factory can be "hard-coded" in the simplest scenario, or can be metatdata-driven for more freedom. It can be as simple or complex as your project requires. I have factories that can check objects dynamically to determine what interfaces are available, for example, and in some cases the objects can communicate with the factory about their specific use and dependencies. In most cases, I prefer to use metadata which is stored in a database. You can read about factory methods and abstract factory patterns to get some ideas about how this all works. The factory doesn't need to know the specific interfaces it delivers - that is, it doesn't need a reference to the dlls and classes - and you can code it with or without references to the interface and implementation dlls depending on your purposes. In the end, it just needs to have a way to know what object(s) to deliver for any specific request. This type of late binding impacts performance to a very minor degree as far as I have found - the actual calls to the methods are not late bound, and the factory itself doesn't itself typlically make any calls on the objects. It can, however - it all depends on what you want it to do.
Lastly - there is the client code. This code needs a reference to the interface dlls only. You would never have a reference to the implementation dlls or the factory dll, at least in the way I typically use them. Note, however, that your factory classes could implement interfaces themselves, and that your client code would have a reference to the factory interface dll. Anway - it is the reference to the interface dlls that allows it to have intelisense in the IDE, and to do syntax checking and discover problems during compilation, and to use early binding. You program against the interfaces, and this code either requests objects from the factories, or is itself created by a factory and handed its configuration dynamically, or follows some other creational pattern. The actual method calls are made against the interface and therefore are not late bound. COM provides the plumbing for this, and understands how to get to the methods directly.
Of course, in VBScript this doesn't work since you can't use anything but the IDispatch interface as far as I have ever seen - in other words, you can't use these "custom" interfaces from VBScript.
So... extra layers? It really depends on what you are trying to do. You get a lot of extra capability using this sort of mechanism with no mearsurable performance hit. This allows you to implement things such as the strategy pattern (as just one example), which should allow you to actually get much better performance than you get from the kinds of code you typically see VB6 programmers doing. I see very little extra complexity from this, myself. At first, it seems complicated, but what I have found is that it actually allows you to do a lot more, and a lot easier, than other schemes for trying to do the same thing.
Recommended reading: Agile Software Development Principles, Patterns, and Practices by Robert C. Martin
For me, this is very valuable stuff to know. That book is written with Java and C++ examples, but most of the ideas translate to any language that has enough OOP features, and this includes VB6. There is a version of the book that has just come out in C# code, but it is essentailly the same book. It is much easier to take advantage of these principles in C# or Java than in VB6 - but it is still very powerful and useful in good old VB6.
Woody Z http://www.learntoprogramnow.com
|
|

November 13th, 2006, 09:01 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 627
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
thanks a lot woody, infact it is the method we use in C# to dynamically load libraries (each library has the same interface and does the same thing... of course in a different way!)
In C# we use LoadLibrary and check if the dll has the interface we want, I never tried to do the same in VB6. In VB6 I use Implements a lot, but only within the same project, that is, a lot of classes with the same interface.
Nice "talking" with you, Woody!
Marco
|
|

November 14th, 2006, 11:31 AM
|
|
Friend of Wrox
|
|
Join Date: May 2006
Posts: 643
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
There are lots of ways to take advantage of interfaces as you note. Additionally, in a language like C# we also have inheritance available. These are both very useful for getting that warm, OOP feeling. For the time being, I perfer OOP to other progamming models I have learned, and as C#/ VB.NET progresses and adds to the OOP features I am trying to take advantage of everything new that comes along.
Nice talking with you too, Marco!
Woody
Woody Z http://www.learntoprogramnow.com
|
|
 |