Why does import need the project name and not just the object? - vb.net

It took me a while to even understand the problem I'm about to describe, so please let me know if the description is confusing...
I have an object called "cProp" that defines a number of sub-classes. To refer to these classes in other files in the project, I have to do something like...
Dim cp = New cProp.InflationRow()
I understand why this is; since the InflationRow is "inside" the cProp, I need to tell it where to find it. Fine.
But this, of course, gets tedious, so sometimes you want to fix it...
Imports cProp
Why doesn't that work? Why do I have to...
Imports ProjectName.cProp
You might wonder why I care, but these files are used in numerous projects with different names. So if I use Imports I have to change the project name in a bunch of places. I am aware that Namespace is likely the solution I want, right?
My confusion stems from the fact that the compiler can figure out just fine which cProp (which is the only one) I'm referring to in the code, so why not in the Imports? I think I'm missing something fundamental here.

It's because your project has a root namespace - you can see this in your project properties. You can delete this in the project properties - this will result in allowing you to simply use the class name from another project. However, namespaces are a good way to organize your classes. In VB, the project defaults to having a root namespace, which you don't see in your code files.
Within your project, since it seems to be all within the same root namespace, you don't have to qualify with the root namespace for code within the root namespace. The "Imports" statements are not within a namespace (only types can be within namespaces) - that's why you have to provide the full qualification there.

Related

Inheritance problem with System.Windows.Forms.Form

I'm studying an older UI customization project (VB.NET Windows forms) by someone else and seem to be running into some kind of problem relating to inheritance. I can duplicate the issue easily, as I'll show, but why I'm baffled is that the project I'm studying is coded the exact same way but doesn't seem affected by this.
Example Code
Let's say we want to create our own form class like so, which would have special properties, event handlers etc.:
Public Class MyFormBase
Inherits System.Windows.Forms.Form
End Class
And then in both our Form1.vb and Form1.designer.vb, we add:
Inherits MyNamespace.MyFormBase
thus replacing the inheritance in Form1.designer.vb which previously said
Inherits System.Windows.Forms.Form
The Error Message
When I try to view the design view of Form1, it is blocked with this error:
The designer could not be shown for this file because none of the classes within it can be designed. The designer inspected the following classes in the file: Form1 --- The base class 'MyFormBase' could not be loaded. Ensure the assembly has been referenced and that all projects have been built.
But, It Works Here...
When I look at the code for the VB.NET Project I'm studying, it's coded exactly the same way, and yet it works/runs without any problem at all. They both inherit from RJMainForm:
form.designer.vb:
Partial Class MainFormDemo
Inherits RJCodeUI_M1.RJMainForm
and form.vb:
Public Class MainFormDemo
Inherits RJMainForm
He said that he created his project originally in VS2012. I tried making the Framework versions match (thus referencing the exact same library files), adding the exact same references etc.
Conclusion
Why does this work in his solution but not mine? I've been through every config file and everything else, but can't find any explanation.
UPDATE #1
The older project that I was learning from included the actual .vb class files, so I was referencing the classes in them when doing my inheritance.
As a test, I did what Jimi suggested and created an Inherited Form. But you have to reference a DLL, which I didn't have - I had several dozen .vb class files spread out over multiple directories. It took some doing, but I managed to turn all of that into a DLL and use it as the basis of an Inherited Form. This Inherited Form approach works without issue and is a great long term solution, since I can now re-use the DLL.
Unfortunately, this brings me no closer to understanding what the actual problem is in my original approach, so I'm still hoping someone will be able to explain what's wrong with my original example code.

Lithium: How do I change the location Connections' and similar classes look for adapters

I've been trying to get Connections to use a customised adapter located at app/extensions/data/source/database/adapter/. I thought extending the Connections class and replacing
protected static $_adapters = 'data.source';
with
protected static $_adapters = 'adapter.extension.data.source';
and changing the connections class used at the top of app/config/bootstrap/connections.php to use app\extensions\data\Connections;
would be enough to get it started. However this just leads to a load of errors where the code is still trying to use the original Connections class.
Is there a simple way to achieve this, or do I have to recreate the entire set of classes from lithium/data in extensions with rewritten class references?
EDIT:
Turns out I was going about this the wrong way. After following Nate Abele's advice, Libraries::path('adapter') showed me where to correctly place the MySql.php file I'm trying to override ;-)
For dealing with how named classes (i.e. services, in the abstract) are located, you want to take a look at the Libraries class, specifically the paths() method, which allows you to define how class paths are looked up.
You can also look at the associated definitions, like locate() and $_paths, to give you an idea of what the default configuration looks like.
Finally, note that the Connections class is 'special' since it defines one path dynamically, based on the supplied configuration: http://li3.me/docs/api/lithium/1.0.x/lithium/data/Connections::_class()
This should help you reconfigure how your classes are organized without extending/overriding anything. Generally you shouldn't need to do that unless you need some drastically different behavior.

How to find and remove unused class files from a project

My XCode project has grown somewhat, and I know that there are class files in there which are no longer being used. Is there an easy way to find all of these and remove them?
If the class files just sit in your project without being part of a target, just click on the project itself in the tree view, so you see all files in the table. Make sure you see the "Target" column in the table view, iterate through your targets and find the files that don't have a check anywhere -> they are no longer compiled.
But if you still compile the classes and they are no longer used, that case is a bit more difficult. Check out this project
http://www.karppinen.fi/analysistool/#dependency-graphs
You could create a dependency graph and try to find orphaned classes that way.
Edit: Link went dead, but there still seem to be projects of Objective-C dependency graphs around, for example https://github.com/nst/objc_dep
if they are C or C++ symbols, then you can just let the linker do the work for you.
if you're looking to remove objc symbols, then try to refactor the class name (e.g. to rename the class), and preview the dependencies that it turns up. if you reference classes/selectors/etc. by strings then... it may not be so effective. unfortunately, you often have to also test manually, to verify that removing a class does not break anything. remember that resources (like xibs) may reference/load objc classes as well.
This is a tricky question due to how dynamic objective-c is as you can never guarantee that a class is not going to be used.
Consider if you generate a class name and a selector at run time and then look up that class, instantiate that class and then call a method on that newly created object using that newly created selector. No where in your code do you explicitly name and instantiate that object but you are able to use it anyways. You could get that class name and selector name from anywhere outside of your code, even from some data from a server some where. How would you ever know which class is not going to be used? Because of this there are no tools that are able to perform what you are requesting.
Searching the project with the class name might be an option, thought it may not be the best solution. Specially it might be time consuming when you have many classes.

How to update a C++ dll without needing to relink the exe with the lib file?

First off , I'm referring to a Windows environment and VC++ compiler.
What I want to be able to do is rebuild a Vc++ dll and maintain compatability with an exe that has already been linked to the lib without having to rebuild the exe or load the dll dynamically using LoadLibrary. In other words, is there a way to add classes and methods to a dll(but not remove any) and ensure the existing entrypoints remain the same?
If you export the functions from using a DEF file and manually specify the ordinals, you should be able to accomplish this.
Reference
http://msdn.microsoft.com/en-us/library/d91k01sh(VS.80).aspx
It depends on how your EXE used the classes from the DLL. Adding new classes should not affect existing entrypoints. Aside from that, however, any the following will affect object size and/or layout, and as such will be a client-breaking change (note that this is technically VC-specific, but most of these apply to any sane implementation):
Removing fields (even private) from classes
Adding new fields (even private) to classes
Adding new base classes to existing classes
Removing base classes from existing classes
Adding new virtual method before an existing virtual method (adding new virtual methods after existing ones is okay, except for the case described in next point)
Adding a new virtual method in a class that is used as base class by another class in the same DLL which also has virtual methods
Changing type of existing fields
Changing signature of existing methods
Making a virtual method non-virtual, and vice versa
As long as you don't add any exported symbols, the ordinals won't change. If you add exported symbols through the standard dllexport mechanism, then that's going to be difficult to control. If you use the old style .xpf symbol file you might be able to control the ordering of the symbols in the lib (although I don't know this for sure - it might still reorder them however it likes), but it's tricky to do C++ symbols this way.
I think that ordinals are rarely used to resolve DLL imports anymore - I think that you have to use .def files to get the linker to use them. So as long as you don't change names or signatures of the exported functions, the .exe should work just fine.

Problem getting type to appear in intellisense from project reference

I'm getting a compiler error saying that "Acme.Business.User" is not defined.
I have a class library project called "Acme.Business" that has "Acme.Business" as the assembly name and root namespace as well. None of the classes use the "Namespace" keyword, so they all should exist in the namespace "Acme.Business".
I also have a class library project called "Acme.Web" that has a project reference to "Acme.Business". Again "Acme.Web" is the project name, assembly name, and root namespace.
Here's the weird part. If I add a class to "Acme.Web" I can type "Imports Acme." at the top and see both namespaces appear in intellisense like you'd expect, but if I try to do "Dim x as New Acme.Business.User" then "Business" doesn't show up in intellisense and I get an error saying "Acme.Business.User" is not defined.
I can't see what I'm doing wrong! Please help. Thanks.
I think you may be misunderstanding how project default namespaces work. The default namespace is a project file setting that simply tells Visual Studio what namespace to add to each file when you add a new class file to the project. If you have removed all of these namespaces from the code files then your types do not exist in that namespace.
This means that all of your types in the Acme.Business assembly live in the global namespace which is probably not what you want. In order to get the desired behavior you will need to add the namespaces back into your code files as that is the only way the compiler will create type names with that namespace.
OK, I figured out that the behavior I was seeing was because I was declaring namespaces within the code in Acme.Web the way I was used to in C# which is to fully qualify it, ie. Namespace Acme.Web.UI.WebControls. I didn't realize that in VB.NET it's building on top of what was specified for the root namespace. I removed the portion that was specified in the "root namespace" setting of my project and it started working. So my namespaces in code for Acme.Web now look like Namespace UI.WebControls.