Contracts Extension on Host View Namespaces

Jan 13, 2008 at 3:49 PM
I'm sure the issue of naming and namespaces has been a very difficult thing to resolve in cerating pipeline buider. Understanding what you're doing here may help work with this as constructively as possible.

My current issue is that my host view namespace retains the "Contracts" extension that I have in my contract declaration. This does not feel correct in the host view.

Can someone explain the philosophy and mechanics on naming, and if its still open, what areas could be adjusted as PipelineBuilder evolves.

I have not yet explred the customization points, nor have I yet checked whether the using singular rather than plural on the Contracts suffix would have had different results.
Jan 14, 2008 at 3:59 PM
The contracts extension definitly should not be part of the namespace in your views. We recommend that your contract assembly, and its default namespace, end with the suffix ".Contracts" rather than simple "Contracts". If you follow this pattern the tool will automatically drop the ".Contracts" extension when it generates the names for the views.

Naming conventions and patterns are pretty much a source of never-ending discussion so the goal for this project was to come up with a naming convention that was good enough for most people but customizable for those that want something different. We therefore added the Namespace attribute that can be applied to an assembly or an individual Contract type that can specify a different namespace, either as a default for an assembly or for an individual type.

In the future we're considering making naming a fully extensible point to our pipeline generator, but we're not there yet.
Jan 15, 2008 at 3:12 PM
Yeah, I totally get the naming challenges. I've been working on this for years.

I'll be happy to offer input when you roll back round to naming questions. At the moment I think there are probably bigger fish to fry.

In the naming arena, I think the biggest issues is that you are pulling the namespace from the assemblyname, not the namespace. Not sure the reason for that, but I think I submitted it as a bug.

Once you get your hot list tidied up, you might want to ask the question here "What are the biggest fish to fry right now?"

Of course if you are vegetarian you'll have to adjust that <g>
Jan 16, 2008 at 12:17 AM
I tried putting ".Contracts" as a suffix on the contracts namespace, and the result I got was that it completely ignored all of the other namespaces I had specified using PipelineHints attributes. Is this by design?
Jan 16, 2008 at 2:44 AM
Here is the logic we use for pulling in the namespace is:


1. If NamespaceAttribute specifies a namespace for the contract in the current segment (views, host view, add-in view, host side adapter, or add-in side adpater) then we will use that namespace
2. Else if the namespace for the contract ends in ".Contracts" the ".Contracts" will be removed and the remaining name will be used, as-is, in the view assemblies. A ".HostSideAdapters" or ".AddInSideAdapters" will be added to the name used in the view in this case.
3. Else if there is an assembly level Namespace attribute specifying a namespace for the current segment then us that namespace
4. Finally, if all of the above cases are unfullfilled it will choose a namspace based on the assembly name of the contract.

If you are interested in looking at the current way names are chosen you can find that in SymbolTable.cs in the PiplineBuilder project: http://www.codeplex.com/clraddins/SourceControl/FileView.aspx?itemId=82893&changeSetId=5304

Given that we have 1,2, and 4 I've been considering removing the ability to apply the namespace attribute onto the assembly itself so that we may remove some of the confusion here. What do you think? Is modifying an assembly level namespace interesting? Should we remove the ability all together, add a new attribute "AssemblyDefaultNamespace", or leave it as is?
Jan 16, 2008 at 2:13 PM
Jesse,

So,the namespace of the contract is ignored unless it has a .Contracts extension?

I think there are bigger fish to fry (like the Value issue in VB that means VB coders have to change the output code everytime).

EXCEPT, I think changing this later would probably be a breaking change. If I have different namespace and assembly names, and I run pipeline builder now, I get the assembly name. Later I run it and get the namespace name. That breaks Host and Add-In code. Ooops.

I do not know what yourlogic was for using the assembly name over the contract namespace when it does not end in .Contracts. But Assemblies are rarely named with the organizational root, and namespaces should ALWAYS begin in this. Nowhere is this more important than when you are crossing organizational boundaries, and AddIns are designed to cross those boundaries. I'm sure you had reason for this decision, but I think you should revisit it and add a 3A - use the contract namespace if there is one.

Oh, and can you use .Contract and .Contracts equally as plurality is hard to keep straight? I don't want to have to remember the period either, but I'll live with that. It would be MUCH better to have that be a configuration value for programmers that don't do symbols in English, but that feels like a phase 2 item.

Also, I think use of the Adapter namespaces should be moved higher in the list. I think it should be added in all cases where an attribute did not specify the namespace for the segment.

I agree that the assembly level attribute is currently confusing. Either removing it or using a different attribute name there would be good. If you have good scenarios, add the new attribute. If you don't remove it and add it back later when you have scenarios. If its going ot be there, I'd like to see the default namespace added once, not added for each segment, with the same rules used elsewhere (adding the adapter extensions) applied.

To summarize, I'd suggest (order of importance):

1) Introduce the contract namespace at 3A, regardless of whether it ends in .Contracts
2) Remove the assembly level Namespace attribute for now, expecting to revisit later
3) Add the adapter extensions unless a segment namespace was explicitly declared
4) Support plural and single for .Contracts
5) Leave the door open for configuration of the contracts identifying extension later
Jan 16, 2008 at 8:15 PM
Jesse,

OK, back to square one on this one....

I want to give my Host View a special namespace to avoid a naming collision with an enum type.

I also have a return value type defined in my contract.

So, whether I add Namespace to the contract/segment or the assembly/segment I ONLY get the specified namespace on the host expression of the contract itself - the altered namespace is not applied to the enum or return type.

How is this supposed to work? If this is a bug, it's a bug and if you'd like me to enter it fine, but I'm not sure where the actual bug is. Do we need the assembly naemspace in case someone has two interface namespaces in the same assembly? And the assembly attribute isn't as much a default namespace as I had thought earlier as it seems the logical one to put on these extra files, unless you want to try to determine that there is only one specified contract namespace.

Also, if you have a secondary interface, such as a return value - not a contract - and place a namespace attribute on that, it works. However, doing so causes the main contract to NOT use the assembly level namespace attribute and instead be in the initial namespace (from the assembly in my case). And the namespace attribute can't go on the enum anyway - so there is currently no way to put all the host stuff in a single namespace.

So, I"m asking here instead of as an issue because I'm not sure what to ask for, but its a mess if you try to define namespaces where you have addiitional files. Feel free to ask if you have questions about what I'm seeing.
Jan 16, 2008 at 8:19 PM
For your suggestion
"1) Introduce the contract namespace at 3A, regardless of whether it ends in .Contracts"

What do you think of the following behavior:

Rather than resort to basing the namespace on the assembly name always base it on the namespace if no other hints are present. To remove ambiguity between the different components we'll need to add the following suffix to the namespace used in each segment.

For a contract type with namespace Foo.Bar

AddInView namespace: Foo.Bar.AddInViews
HostView namespace: Foo.Bar.HostViews
Shared View namespace: Foo.Bar.Views
Add-In Side Adapter namespace: Foo.Bar.AddInSideAdapters
Host Side Adapter namespace: Foo.Bar.HostSideAdapters

The latest source check-in contains fixes for your suggestions 3 and 4 above.

1,2, and 5 are all easy to do from a coding standpoint, but I just want to make sure that they are the right thing to do before checking it in.
Jan 16, 2008 at 8:32 PM
Jesse,

I'm sorry to be persistent in these details, but ...

What's the logic for demanding the period in the .Contracts to recognize the namespace, but not using a . when adding the adapter namespace suffxes?

namespace GenDotNet.LinqGeneratorHostAdapers

rather than

namespace GenDotNet.LinqGenerator.HostAdapers

I'm anal about namespaces overall, and would probably prefer the dots, but dislike it when they are not consistenly used to differentiate parts of a whole (what's happening here).
Jan 16, 2008 at 8:44 PM


KathleenDollard wrote:
Jesse,

OK, back to square one on this one....

I want to give my Host View a special namespace to avoid a naming collision with an enum type.

I also have a return value type defined in my contract.

So, whether I add Namespace to the contract/segment or the assembly/segment I ONLY get the specified namespace on the host expression of the contract itself - the altered namespace is not applied to the enum or return type.

How is this supposed to work? If this is a bug, it's a bug and if you'd like me to enter it fine, but I'm not sure where the actual bug is. Do we need the assembly naemspace in case someone has two interface namespaces in the same assembly? And the assembly attribute isn't as much a default namespace as I had thought earlier as it seems the logical one to put on these extra files, unless you want to try to determine that there is only one specified contract namespace.

Also, if you have a secondary interface, such as a return value - not a contract - and place a namespace attribute on that, it works. However, doing so causes the main contract to NOT use the assembly level namespace attribute and instead be in the initial namespace (from the assembly in my case). And the namespace attribute can't go on the enum anyway - so there is currently no way to put all the host stuff in a single namespace.

So, I"m asking here instead of as an issue because I'm not sure what to ask for, but its a mess if you try to define namespaces where you have addiitional files. Feel free to ask if you have questions about what I'm seeing.

I'm not quite following your scenario here. Can you post a small snipped that shows the contracts and the PipelineHints attributes your using here?
Jan 21, 2008 at 3:23 PM
Sorry I was slow on this

Yes, I like basing namespaces on namespaces only.

What if the namespace is empty though? Do you want to cover that and have just HostView or do you want to resort to the assembly name if the namespace is null? Just don't have it crash with namespaces if .HostView.

-----

What do you think of the following behavior:

Rather than resort to basing the namespace on the assembly name always base it on the namespace if no other hints are present. To remove ambiguity between the different components we'll need to add the following suffix to the namespace used in each segment.

For a contract type with namespace Foo.Bar

AddInView namespace: Foo.Bar.AddInViews
HostView namespace: Foo.Bar.HostViews
Shared View namespace: Foo.Bar.Views
Add-In Side Adapter namespace: Foo.Bar.AddInSideAdapters
Host Side Adapter namespace: Foo.Bar.HostSideAdapters

Jan 21, 2008 at 3:40 PM
Back to square one in that its not working for me and because we may need the default namespace for this scenario.


KathleenDollard wrote:
I want to give my Host View a special namespace to avoid a naming collision with an enum type.


Using a PipelineHint attribute added namespace to Host View



KathleenDollard wrote:
I also have a return value type defined in my contract.


I have an enum and return type also in my contract - thus I'm working with several files in my views/adapters


KathleenDollard wrote:
So, whether I add Namespace to the contract/segment or the assembly/segment I ONLY get the specified namespace on the host expression of the contract itself - the altered namespace is not applied to the enum or return type.


Using both approaches to the PipelineHit, I do not get the specified namespace on all generated files, just on the Contract - the enum and return type should have the same namespace

Should I put the namespace I want for the generation of all three file types as an Assembly namespace? If so, there's a bug it doesn't work. Also, we just discussed dropping the Assembly Namespace, or at least renaming it to Default (which would be cool).

Should I repeat the namespace attribute on each element of the overall contract? (ick in principal as its redundant and screw-up-able). If so, you need to add the ablity to put the attribute on enums where it fails at present.


KathleenDollard wrote:
Also, if you have a secondary interface, such as a return value - not a contract - and place a namespace attribute on that, it works. However, doing so causes the main contract to NOT use the assembly level namespace attribute and instead be in the initial namespace (from the assembly in my case). And the namespace attribute can't go on the enum anyway - so there is currently no way to put all the host stuff in a single namespace.


This feels like a V1 bug.

I have not been able to put all my stuff in the same namespace without resorting to wacky assembly naming. I want them in the namespace GenDotNet.LinqGenerator.<whatever>. They are in the namespace GenDotNet.LinqGenerator.Contracts via Project level namespaces in VB (not in this code) but that should not be discerible in IL. I've currently removed all the attributes and am forcing the assembly for success with this version.

Plase let me know if you still have questions. I'm really looking forward to the next release. The Value bug is a pain and I see that's fixed in next rev

Public Enum GeneratorCategory
None = 0
Object
Table
CreateStoredProc
UpdateStoredProc
DeleteStoredProc
RetrieveStoredProc
RetrieveChildrenStoredProc
RetrieveHierarchyStoredProc
RetrieveSetStoredProc
Api
End Enum

Public Interface IGenerateReturn
Inherits AddIn.Contract.IContract
Property FileName() As String
Property OutputText() As String
End Interface


<AddInContract()> _
Public Interface ILinqGenerator
Inherits AddIn.Contract.IContract

Function SetXmlDocument( _
ByVal inputXml As String) _
As String

Sub ClearXmlDocument()

Function GetFileName( _
ByVal objectName As String, _
ByVal category As GeneratorCategory, _
ByVal assemblyFileName As String, _
ByVal templateName As String) _
As String

Function Generate( _
ByVal objectName As String, _
ByVal category As GeneratorCategory, _
ByVal assemblyFileName As String, _
ByVal templateName As String) _
As IGenerateReturn

Function GetOutput( _
ByVal storedProcName As String, _
ByVal category As GeneratorCategory, _
ByVal assemblyFileName As String, _
ByVal templateName As String) _
As String

Function Generate( _
ByVal objectName As String, _
ByVal category As String, _
ByVal assemblyFileName As String, _
ByVal templateName As String) _
As IGenerateReturn

Function GetOutput( _
ByVal storedProcName As String, _
ByVal category As String, _
ByVal assemblyFileName As String, _
ByVal templateName As String) _
As String


End Interface


Jan 21, 2008 at 6:58 PM
For enum's in particular I found a bug where the namespace customizations were not being applied. I've fixed that and will be checking the fix in to the source code either today or tomorrow (it will also let you apply the attribute to enums).

The general goal for all of this though is that you shouldn't have to worry about the attributes and that in the general case if you simply apply the ".Contracts" suffix onto the namespace you want to use in your view for your contract type then everything should just work out nicely.

The latest source drops relaxed this to either ".Contract" or ".Contracts". Does this not work for you for some reason? Are there scenarios you're interested in where you need something different? Or are there bugs where this stated behavior isn't actually taking place.




If any of the bugs currently marked fixed are causing you a lot of grief you can download the latest source and build on your own machine and you should be in good shape. You'll need to build all the assemblies, build the installer package, uninstall the current version, and then run the new setup exe.