Replacing company and product name in namespace and library names - c#

The standard recommendation for names of namespaces goes like this:
<Company>.(<Product>|<Technology>)[.<Feature>][.<Subnamespace>]
Similarly, for the names of assemblies Microsoft guidelines recommend:
<Company>.<Component>.dll
My place like many other small and medium sized companies went through several name changes as well as product name changes which make old namespace and assembly names obsolete. Changing it every year or two as marketing preferences change is quite a pain. Leaving the mix of the old and new namespaces is even bigger pain. In essence, I find the recommendation does not work well for many of us.
Anyone found a good way around it? Using 'technology' and 'component' instead of product name may help, but I am really struggling with what to use instead of company name?
Maybe I should accept that these names are dynamic and need to be 're-factored' just like the code...

I've had a similar situation. A couple thoughts...
Does your assembly naming matter? Is it visible to your customers? If your assembly names are visible, you could always change the name of the assemblies without changing the namespaces. Might be less of a pain. But if you're just deploying a server, and your customers will never see the assembly filenames, then maybe this isn't worth investing a lot of time in.
(And yes, it kills a little part of me to write that. Because I hate stuff like this. But sometimes it's just not worth it.)
Perhaps you could use a code-name for the product, and leave the company out. The codename could remain constant, or only change on major releases, when you would be updating references anyway.
This is a bigger change, but... I've had some good luck running a NuGet server for my project's assemblies. This may help manage some of the pain of changing - publish a new package with the new name, and upgrade all the users of that package. Still a pain? Yup. But maybe easier to pull off than managing assembly references directly.

Related

Storing version change information in a specialized Assembly Attribute

After a conversation with a colleague about storing version change log type information in a specialized assembly attribute, I thought I'd ask the wider community for their thoughts.
I.e, each assembly has a version field, it's not a large step to consider rudimentary version change information stuffed into a specialized attribute in the assembly.
Please note this would be for in-house applications, not public.
From the conversation:
Pros might be
Change information is stored in the assembly with a version number
Change information can be enumerated from an assembly for various reasons
Version and change information is in the one place
Change logs are usually associated with an assembly
However I can't really come up with good fundamental arguments why this would be a bad idea.
Cons might be
won't look good in the assembly extended property information?
bloat the assembly?
Attack vector?
Example:
[assembly: AssemblyChangeInformation(
{1.0.0.1, "Added Something",
"Done Something else"
...}),
{1.0.0.2, "Some bug fix"},
{1.0.0.3, "blah ..."})]
Please be aware I'm not for or against this idea.
I'm just wondering what the pros and more specifically the cons are, so I can go back to the powers-that-be with an enlightened argument for or against.
The information should be stored in a revision control software like SVN, as long as you write log into SVN when you commit code changes and remember to increment the version number at each build you can easily associate the right assembly with the change history, there is no need to store the information in "one place".
If you store this information in attributes, you need to develop a decent viewer - or at least some helper code - to view the change logs. Can't beat SVN, right?

How to handle your code that later versions of the framework include?

I have to work with an old version of Mono in Unity projects. I find myself recreating some classes and extension methods that exist in later versions of .NET. Should I be marking these with an attribute that will make it easy to take them out at a later point, just wait for the inevitable errors, and delete the duplicate code, or take some other approach I'm not familiar with yet? If the attribute route is the way to go, is there already an appropriate attribute created for this kind of thing?
Here's what I'd like:
[PresentInDotNET(3.5)]
I fill in the version and get alerted when the framework is at that level or higher.
Split them off to a separate assembly, and change the set of assemblies that make up the final delivery based on the .NET version. You need to rebuild your main assembly to refer to the correct assemblies (depending on whether Foo is in MySystem or System), but as long as you keep namespaces identical, that's all. If you are not even interested in keeping compatibility with older versions, you can simply delete classes from this assembly as they become available.
Alternatively, if the classes/extension methods you are recreating are not interesting (in the sense that you gain nothing by having .NET supply them for you), simply put them in their separate namespace and accept that you are duplicating code already present in newer versions. It doesn't matter a whole lot which assembly gets the job done, after all, as long as it happens.
Whatever you do, try to avoid going the route of #ifdefs, runtime discovery, and other conditional code, as this is much harder to maintain.
How about adding "// TODO" comments for places like this? Visual Studio will display these in the Task window and you can get at them pretty easily.

Two namespaces of the same class

we are changing the name of our product, so i also want to rename the namespaces of our
framework-classes. But now i have the problem, that i don't know in which programms and scripts our namespaces are used. Is there a way in c#, to locate the same class in two different namespaces?
I know the solution, that i could inherited from my classes in the new namespace, but this is a very bad solution i think. So I have no idea how to solve this problem, because simply renaming all namespaces doesn't help and will cause a lot trouble.
Thank you!
If external scripts are referencing your assembly using the old namespace names then those names will have to remain in your assembly in you wish to continue to use those scripts. If you also want to create new namespace names to reflect the new name of your product, those names will also need to be hardcoded into your assembly. This will inevitably lead to problems!
I would recommend one of the following:
Leave the namespace names as they are.
Rename the namespaces in full and update the Python scripts at the same time.
I would definitely not recommend the faux 'inheritance' method, or any other solution which results in duplication within the assembly.
You could search the whole project / solution of course, but that seems sort of messy and time-consuming too, if you've got more than a trivial project.
Are you using Resharper? For this type of task, you definitely should be. If so, there is a chance this could at least help you on your way:
Rename the folders your source files are in in the Visual Studio Solution Explorer (this should in theory be easier than looking at each source file one by one, right?).
Now open one source file that you know will have the wrong namespace due to a renamed folder. It should appear with a blue squiggly line, as in the picture below.
Use the Resharper tip (pyramid to the left, or Alt + Enter) to open the context meny thingy also shown below.
Select Find all issues of this type in scope, and select Solution as your scope. That might at least help you get an overview of which classes you need to change the namespaces for, and go through them and change them systematically.
As for your scripts, I would guess that you best bet is to do a plain text search for the old namespaces - possibly a search and replace. Perhaps you can include your scripts in a VS solution, and use the built in search there to scan and fix them. That might at least ease the pain a little..

Restricting using strong named dlls functionality

I'm trying to think of a way that prevents others from using your published dlls. For example let's say you create a cool lightweight WinUI photo processing tool that's separated into several assemblies. One of them is your precious filters.dll assembly that basically does all of the core filtering work. Once you publish your application, how can you prevent others from taking this filters.dll and using it in other projects?
I've already tried to look at the StrongNameIdentityPermissionAttribute which has a good example here but it doesn't seem to work for me, the code just works without throwing any security exceptions..
Any ideas?
Strong names have nothing to do with preventing or inhibiting reverse engineering. They only serve to stop people substituting assemblies with hacked versions - and only if people havent turned off strong name verification. There's nothing to stop people taking your code, ILDASMing or Reflectoring and re-ILASMing as they see fit.
InternalsVisibleTo and friends are on an honour system at the compiler level too, so not much use for what you're looking for (although for some obfuscators, internals get more agressively obfuscated than publics by default - though this can generally be overcome). My main concern here is to point out that jsut because something is 'internal' doesnt bestow on it any magic code protection pixie dust that stops reverse engineering.
Most of this stuff re why these sort of approaches arent a solution for code protection is summarised very well in this article
There are also code protection products on the market that go beyond obfuscation which sound like the tool for the job you describe.
One method that may work for you is to declare the the methods and classes in the filter assembly to be internal and explicitly specify the assemblies that can access it as "friends".
You do this with an assembly declaration (ususally in assemblyinfo) like:
[assembly:InternalsVisibleTo("cs_friend_assemblies_2")]
see Friend Assemblies for more info.
Also make sure you obfuscate the assembly or people can dig into the code with reflector.
Don't bother worrying too much about protecting your .NET code. If you deploy it to someone elses computer, and that person wants to use or read your code, they will.
If your code is valuable enough you need to keep it on a computer you control (such as a web server) and guard against unauthorised access.
Obfuscation will only slow determined people down. Strong naming and signing is not used to protect your code, but instead to ensure that the user can confirm the code originates from who they expect it to come from (ie ensure it hasn't been tampered with).

Best practices for assembly naming and versioning?

I am looking out for some good practices on naming assemblies and versioning them. How often do you increment the major or minor versions?
In some cases, I have seen releases going straight from version 1.0 to 3.0. In other cases, it seems to be stuck at version 1.0.2.xxxx.
This will be for a shared assembly used in multiple projects across the company. Looking forward to some good inputs.
Some good information from this article on Suzanne Cook's blog on MSDN (posted 2003-05-30):
When to Change File/Assembly Versions
First of all, file versions and assembly versions need not coincide
with each other. I recommend that file versions change with each
build. But, don’t change assembly versions with each build just so
that you can tell the difference between two versions of the same
file; use the file version for that. Deciding when to change assembly
versions takes some discussion of the types of builds to consider:
shipping and non-shipping.
Non-Shipping Builds In general, I recommend keeping non-shipping assembly versions the same between shipping builds. This
avoids strongly-named assembly loading problems due to version
mismatches. Some people prefer using publisher policy to redirect new
assembly versions for each build. I recommend against that for
non-shipping builds, however: it doesn’t avoid all of the loading
problems. For example, if a partner x-copies your app, they may not
know to install publisher policy. Then, your app will be broken for
them, even though it works just fine on your machine.
But, if there are cases where different applications on the same
machine need to bind to different versions of your assembly, I
recommend giving those builds different assembly versions so that the
correct one for each app can be used without having to use
LoadFrom/etc.
Shipping Builds As for whether it’s a good idea to change that version for shipping builds, it depends on how you want the binding to
work for end-users. Do you want these builds to be side-by-side or
in-place? Are there many changes between the two builds? Are they
going to break some customers? Do you care that it breaks them (or do
you want to force users to use your important updates)? If yes, you
should consider incrementing the assembly version. But, then again,
consider that doing that too many times can litter the user’s disk
with outdated assemblies.
When You Change Your Assembly Versions To change hardcoded versions to the new one, I recommend setting a variable to the version
in a header file and replacing the hardcoding in sources with the
variable. Then, run a pre-processor during the build to put in the
correct version. I recommend changing versions right after shipping,
not right before, so that there's more time to catch bugs due to the
change.
One way to define your versioning is to give semantic meaning to each portion:
Go from N.x to N+1.0 when compatibility breaks with the new relase
Go from N.M to N.M+1 when new features are added which do not break compatibility
Go from N.M.X to N.M.X+1 when bug fixes are added
The above is just an example -- you'd want to define the rules that make sense for you. But it is very nice for users to quickly tell if incompatibilities are expected just by looking at the version.
Oh, and don't forget to publish the rules you come up with so people know what to expect.
Semantic Versioning has a set of guidelines and rules as to how to apply this (and when). Very simple to follow and it just works.
http://semver.org/
The first thing I would recommend is to become familiar with the differences between the Assembly version and the File version. Unfortunately, .NET tends to treat these as the same when it comes to the AssemblyInfo files in that it usually only puts AssemblyVersion and allows the FileVersion to default to the same value.
Since you said this is a shared assembly, I'm assuming you mean it's shared at a binary level (not by including the project in the various solutions). If that's the case you want to be very deliberate about changing the Assembly version as that is what .NET uses to strong name the assembly (to allow you to put it in the GAC) and also makes up the "assembly full name". When the assembly version changes, it can have breaking changes for the applications that use it without adding assembly redirect entries in the app.config file.
As for naming, I think it depends on what your company naming rules are (if any) and the purpose of the library. For exmaple, if this library provides "core" (or system level) functionality that isn't specific to any particular product or line of business, you could name it as:
CompanyName.Framework.Core
if it's part of a larger library, or simply
CompanyName.Shared
CompanyName.Core
CompanyName.Framework
As far as when to increment version numbers, it's still rather subjective and depends on what you consider each portion of the build number to represent. The default Microsoft scheme is Major.Minor.Build.Revision, but that doesn't mean you can't come up with your own definitions. The most important thing is to be consistent in your strategy and make sure that the definitions and rules make sense across all of your products.
In almost every version scheme I've seen the first two portions are Major.Minor. The major version number usually increments when there are large changes and/or breaking changes, while the minor version number usually increments to indicate that something changed which did was not a breaking change. The other two numbers are considerably more subjective and can be the "build" (which is often times a serial date value or a sequentially updating number that changes each day) and the "revision" or patch number. I've also seen them reversed (giving Major.Minor.Revision.Build) where build is a sequentially incrementing number from an automated build system.
Keep in mind that the assembly major and minor versions are used as the type library version number when the assembly is exported.
Finally, take a look at some of these resources for more information:
http://msdn.microsoft.com/en-us/library/51ket42z.aspx
http://msdn.microsoft.com/en-us/library/system.reflection.assemblyversionattribute.aspx
http://blogs.msdn.com/suzcook/archive/2003/05/29/57148.aspx

Categories