Use namespace alias in subsequent Imports? - vb.net

I have a huge library with lots of namespaces and classes, nested to >10 levels deep. In most projects I will be using only one of the most nested namespaces at a time, so there is some kind of root, above which I will not Import. For example, the object I need lies within:
Imports MyObject = ns1.ns2.ns3.ns4.ns5.MyObject
And another one in:
Imports MyOtherObject = ns1.ns2.ns3.ns4.ns5.ns6.MyOtherObject
Problem is that ns1 and other nsX can be very long name, so the whole lines goes way off screen and it's hard to follow. I was hoping you could declare an alias like this:
Imports MyRoot = ns1.ns2.ns3.ns4.ns5
And then use the above:
Imports MyObject = MyRoot.MyObject
Imports MyOtherObject = MyRoot.ns6.MyOtherObject
But it does not work like this, i.e. Imports do not see each other.
I tried using project-wide settings - same behavior. Is there a solution or a workaround?
I was thinking maybe it's possible to package namespaces into another namespace? (similar to how My works, but I could not find any good source on how to implement this)

Related

How do you use a function in a namespace?

I have the following Namespace with 2 functions in it that I want to use, but I'm not sure how I access them?
I tried importing ("using" for C#) but those 2 functions arent in the namespace.
Do I have to create a class and create those functions myself?
The weird thing is, those 2 functions are found within a different namespace:
Regardless of where it is, how would I turn these into functions I can call from my code?
When I try to access those functions in my code, they don't know up :
I think you're getting a bit confused. It's understandable with namespaces.
Gds.GoogleMap.UltimatePlus.Math.Mathservice is not a namespace name. The namespace name is Gds.GoogleMap.UltimatePlus.Math . MathService is the class name.
If you put the statement
using Gds.GoogleMap.UltimatePlus.Math;
at the top of your file then all you need to do to declare a new object is to say:
MathService myService = new MathService();
assuming it has a default constructor.
Give it a try.

Override Import's takeover of Collection?

I'm trying to create a new Collection -
Dim theSet as New Collection
but, I am using the Textsharp PDF creator in my project -
Imports iTextSharp.text
Imports iTextSharp.text.pdf
and Textsharp apparently creates it's own "collection" Namespace, removing the VB.NET one.
Is there a way to override this and use the VB.NET Collection statement?
Thanks
There is not much you can do about a library polluting the namespace with common words like that. It has a Java background and counted on a case-sensitive language. You'll have to help the compiler by being explicit that you meant to use the VB.NET Collection class and not the iTextSharp.pdf.text.collection namespace. Either type out of the full class name to disambiguate:
Dim theSet as New Microsoft.VisualBasic.Collection
Or add an alias:
Imports VBCollection = Microsoft.VisualBasic.Collection
...
Dim theSet as New VBCollection
That same aliasing trick works on the library as well:
Imports Pdf = iTextSharp.text.pdf
And you'll have to prefix Pdf. whenever you want to reference a type from that namespace.

Can I provide a better name for a pre-defined class

I have a class that has been pre-defined by an XSD but the name is long and confusing. I can't rename the class directly. Is there a way to create a new class with a better name and inherit the poorly named one without having to write a bunch of setters and getters since the XSD could potentially change over time?
I tried just creating an empty class like this:
Public Class TaskDetails : Inherits ExternalResponseTaskDetailTaskDetail
End Class
And that would work fine, except I get a casting error when I try to
Dim td as TaskDetails = ertdtd
This seems like I'm asking a very stupid question, but try as I might, I can't get my Google-Fu working for me on it. The long class name does make sense inside the library I'm working in, but outside the library, it really doesn't. Especially since the library contains an ExternalRequestTaskDetails class and ExternalRequestTaskDetailsTaskDetails is an element contained within it.

Declaring an object without using the namespace of the class

I have a class library project named MyWidget, with the only class being named MyWidget.
In another project, I've added a reference to my class library, and in my new class, I've tried typing in
Imports MyWidget
and
Imports MyWidget.MyWidget
However, later in my class when I try to create a new reference, Visual Studio is not allowing me to type in this:
Private widget As MyWidget
However, Visual Studio is giving me a "Type Expected." error and forcing me to also include the namespace, like so:
Private widget As MyWidget.MyWidget
I read the MSDN documentation regarding the Imports statement. I should be able to leave off the namespace when declaring the object because I have the imports statement at the top of the program. I've tested this with standard namespaces, and it works fine, but when I try it out with my class, it doesn't.
Am I missing something in the MyWidget class that will allow me to leave off the namespace when declaring the object?
I also tried renaming the namespace to MyClasses, thinking maybe that Visual Studio was getting the namespace confused with the class. However, even with
Imports MyClasses.MyWidget
I still get an error when trying to define a MyWidget object without the MyClasses Namespace.
Since the Namespace and Class have the same name the compiler gets confused when you try to instantiate MyWidget, despite the Imports statement. Just because there is an Imports statement, doesn't mean you can't fully quanlify a type (even if you have Imports System.IO.File, you can still call System.IO.File.WriteAllText), thus the confusion on the compilers end. An alternative would be to use an Alias.
Imports AWidget = MyWidget.MyWidget
Then..
Dim objWidget As New AWidget
It appears that the issue was the namespace and the class having the same name. After changing the namespace to MyClasses and the class to MyWidget, the following statements worked:
Imports MyClasses
...
Private widget as MyWidget

Interfaces and hungarian notation

Please have a look at the following question: What's the naming convention for classes in the DataAccess Project?
JDK talks about using Namespaces to separate the Data Logic Layer and the Business Logic Layer and not to use Hungarian notation to name interfaces e.g. IPersonDAL for the data access layer. I have followed the recommendations of this answerer in the code below:
Imports com.app.BusinessLogicLayer.Interfaces
Imports com.app.DataLogicLayer.Interfaces
Namespace BusinessLogicLayer
Public Class Order
Implements com.app.BusinessLogicLayer.Interfaces.IOrder
Public Sub Insert()
Dim IOrder As com.app.DataLogicLayer.Interfaces.IOrder = New com.app.DataLogicLayer.Order
End Sub
End Class
End Namespace
Namespace DataLogicLayer
Public Class Order
Public Sub Insert()
End Sub
End Class
End Namespace
Namespace BusinessLogicLayer.Interfaces
Public Interface IOrder
End Interface
End Namespace
Namespace DataLogicLayer.Interfaces
Public Interface IOrder
End Interface
End Namespace
Classes in the business logic layer e.g. Order implement interfaces (IOrder from Business Logic Layer) and use interfaces (IOrder from Data Logic Layer) i.e. the presentation layer communicates with the Business Logic Layer and the Business Logic Layer communicates with the data logic layer with interfaces. Notice that because of this reason; interfaces have to be fully qualified with the namespace. For this reason; isn't it better to name interfaces using hungarian notation e.g. IPersonBLL and IPersonDAL or am I missing something?
Well, this is a subjective topic, but here goes...
Firstly, avoid abbreviations like DAL. Code Analysis yells about acronyms and abbreviations; you're supposed to write it out. In my experience it's wise advise. Opening up ancient code that's full of abbreviations causes a lot of unnecessary WTF moments (pun intended).
Even when spelling things out, when you have 50 classes sitting in your BusinessLogic folder like this:
Company.Product.BusinessLogic
PersonEntity
OrderEntity
MaterialEntity
EmployeeEntity
CustomerEntity
etc.
My gut tells me it's time to refactor. I feel it's better to move the Entity tag to the namespace, so you have this:
Company.Product.BusinessLogic.Entity
Person
Order
Material
Employee
Customer
etc.
Same things applies to interfaces.
This also makes it easier to refactor. If I want to start calling my Entities "BusinessObjects", I just have to rename the namespace, not the class names and file names.
It can be a pain to qualify your class names, but you normally only have to specify the parent namespace, not fully-qualify them. Resharper -> Cleanup Code does wonders here.
In summary, I would not add Hungarian notation to my interface/class name just to make references easier to deal with.
Update: Example
Data Access Layer:
Namespace Company.Product.DataAccess.Adapter
Public Class Product
End Class
End Namespace
Business Layer:
Imports Company.Product.DataAccess
Namespace Company.Product.BusinessLogic.Entity
Public Class Product
Dim adapter As New Adapter.Product()
End Class
End Namespace
User Interface (ideally your UI should only interact with the business layer, never with the data layer directly):
Imports Company.Product.BusinessLogic
Namespace Company.Product.UserInterface.Webpage
Public Class Product
Dim productEntity As New Entity.Product()
End Class
End Namespace
Notice that because of this reason; interfaces have to be fully qualified with the namespace. For this reason; isn't it better to name interfaces using hungarian notation e.g. IPersonBLL and IPersonDAL or am I missing something?
I see what you are saying, but I don't understand why fully-qualifying the names is bad or why it would be "better" to name the interfaces using "Hungarian" notation. (And I say this as a truly unrepentant fan of Simonyi's apps Hungarian.)
Remember that regardless of the names and locations of the classes/interfaces, the compiler is going to produce the same object code. The apparent nesting level is not going to "slow down" your code to any perceptible degree.
If it really bothers you to type out the names (and Intellisense is of no consolation), you can always use something like a namespace alias with a using directive. But I'd be careful with overusing theseā€”I think it makes the code even harder to read.