What is the best way to implement versioning of a binary? - c#

I am thinking of the following design:
static class AppVersion
{
public static string BuildDate
{
get; set;
}
public static string Version
{
get; set;
}
public static string GetVersion
{
get; set;
}
}
A few questions on this:
How can I get the build date?
How can I print a date in a nice format?
How can I obtain and print the Visual Studio version in a nice format?
It is probably a bad idea to hard code the version into the binary, so I put the version into assembly information. How can I programmatically get it?

I think your first questions are a matter of taste. You could use String.Format to get any style you want. Regarding your last question:
System.Reflection.Assembly.GetExecutingAssembly().Version
returns the version number of the current assembly and:
typeof(SomeTypeInSomeAssembly).Assembly.Version
will return the version number of the assembly containing the specific type.

We run all our production builds through CruiseControl.NET, which (among many other things) has the facility to version builds.
We then have a snippet of code that applies the CC.NET-generated build number (and other stuff) to AssemblyInfo.cs just before it's given to the compiler for building.
I suppose you could use a similar technique to insert the build date into a constant in some class somewhere in your app.

For build Date look at
http://dotnetfreak.co.uk/blog/archive/2004/07/08/determining-the-build-date-of-an-assembly.aspx
For the version / Get Version look at the System.Reflection.Assembly name space.
As for printing the date in a nice format, you'll want to either use the extension methods built off of DateTime class such as .ToShortDateString() or CultureInfo.

For build date or timestamp, you can embed it into the assembly when building.
For how to do that, see here.

Related

protobuf-net converts List<T> to List_T class when using .ToProto()

I have a requirement to take a library of C# classes that implement protobuf-net, and convert them into .proto files, which need to be converted using protoc into .py files. I understand that the .ToProto() function does this just fine, but I came up against an issue involving collections and generics when converting from .proto to .py files. When trying to serialize a list of DateTimes, for example I get the following error X.proto:64:13. "List_TimeSpan" is not defined. As this had not caused an issue upon serialization into a protobuf file, I wasn't aware of this situation at the time.
I am currently using proto-buf.net 2.3.2 for this project; it's the version some of my other work has been done with and I am aware that this could just be solved with a version upgrade. I'm just not sure if that is the answer with the digging I've done so far. If there's something else that I'm missing, I would truly appreciate any help that can be thrown my way.
If we consider:
[ProtoContract]
public class Foo {
[ProtoMember(12)]
public List<DateTime> Times { get; } = new List<DateTime>();
}
then GetProto<T>() in both v2.3.2 (the version mentioned in the question) and v2.4.4 (the current default version) generate:
syntax = "proto2";
import "protobuf-net/bcl.proto"; // schema for protobuf-net's handling of core .NET types
message Foo {
repeated .bcl.DateTime Times = 12;
}
So on the surface of it, it should already be just fine. If you're doing something more exotic (perhaps using a list in a dictionary value?), I'd be happy to help, but I'm going to need more of a clue as to what you're doing. Posting some C# that shows the thing you're seeing would be a great place to start.
Note that when protobuf-net first came around, there was no agreed transmission format for date/time-like values, so protobuf-net made something up, but it turns out to not be a convenient fit for cross-platform work; the following is a hard breaking change (it is not data compatible), but if possible, I would strongly recommend the well-known format that Google added later:
[ProtoContract]
public class Foo {
[ProtoMember(12, DataFormat = DataFormat.WellKnown)]
public List<DateTime> Times { get; } = new List<DateTime>();
}
which generates:
syntax = "proto2";
import "google/protobuf/timestamp.proto";
message Foo {
repeated .google.protobuf.Timestamp Times = 12;
}

C# code expansion/injection in compile time

I'm looking for a way to expand/inject code at compile time,
something like templates/macros/snippets...
Let's say I wrote this code in a lot of places in my application:
[JsonObject("MyProperty")]
private string MyPropertyJson { get; set; }
public object MyProperty { get; set; }
The MyPropertyJson property is used for EF mapping purposes only so I save the value is a JSON string in DB but for class users, they only know about MyProperty property.
What I want to do is, at compile time, MyPropertyJson to be expanded to this:
private string MyPropertyJson
{
get
{
return JsonConvert.SerializeObject(MyProperty);
}
set
{
MyProperty = JsonConvert.DeserializeObject(value);
}
}
I want this to be done in the output binaries only without affecting the source code.
I know about Unity, PostSharp, Aspect-Injector, etc.. but they don't achieve what I want because by using them, I have to use some reflection to find & manipulate MyProperty but I want to expand it exactly like it's been written in the same class with access to all class internals.
It's exactly like code snippets but to be expanded during compilation phase.
A solution that doesn't cost anything extra and is supported within Visual Studio is T4 aka Text Templates. However, it does require you install the VS SDK (eg, 2015) and Modeling SDK (eg, 2015) of the version of VS that you use.
For my base class libraries, I end up dedicating an assembly for utils to use in the T4 code I write in production code. I use it in places like rolling out read/writes for primitives in IO code (eg, .TT and .CS). Although you don't have to do this if you don't need much/complex compile time code gen.
I was able to achieve my requirement by writing a BeforeBuild msbuild target to call an external console app which I've developed to:
Copy source files that will be rewritten to a temp folder
Rewrite the source code in the temp files
Added conditional Compile tag to the .csproj file to include manipulated source files instead of the original ones
It works like a charm :)
I'm working on a generic engine for this task and will commit it to github once finished.
The is a way to kind of get what you want.
Using implicit operators
That would need to create your own json object class for example, then add these:
class JsonObject {
public object obj;
public static implicit operator string(JsonObject target) {
return Json.SerializeObject(target.obj);
}
}
But that won't really do what you really wanted. Almost the same as creating a new class and add functions.

Code generation from external text template -- should I write regular C# tool or use text template tool?

I had so far just a little experience with T4, that's why I am asking.
I have such problem -- instead of having template which transforms itself into C# code (I would use T4 then) I have external file (template) which I would like to convert to C# code. Here (just an example!) I am building pretty limited (very limited) ORM. So my template looks like this:
Entry
*ID int
*Lang string
Text string
and this should be transformed to full class, which starts like this:
public class Entry
{
public int ID { get; set; }
public string Lang { get; set; }
public string Text { get; set; }
public object[] PrimaryKeys { get { return new object[] { ID, Lang }; } }
public void ReadRecord(...
}
Question -- what is my next best step: should I my own converted or should I use T4 (or other similar tool).
The one advantage of my own tool I can think of is that IF I have/spend enough time, I could omit template file and create C# relying directly on database structure (in this case) instead of template file.
While answering please make this clear if you recommend your solution in both cases (input: text template vs. binary file, like db).
Remark: please, please, don't start with "why don't you use NHibernate/LS2/EF...". Thank you!
I think T4 will work just fine for your needs. Check out the section "Design-time T4 text templates" in this MSDN link. It describes reading an XML configuration file to drive the code generation. You basically put the code that reads the input file into the first part of the .tt file, and then later reference what you read in as you lay out the classes.

Shortcut to creating many properties all with default get / set body

Is there some shortcut way of handling multiple properties on a class (say 50 spanning string, int, datetime, etc). They will all have the same simple declaration such as
private int myInt;
public int MyInt
{ get { return myInt; }
set { myInt = value; }
}
private datetime someDate;
public datetime SomeDate
{ get { return someDate; }
set { someDate = value; }
}
The reason, is I have a class that will be "bound" to data entry textbox type fields and such. By just making them "public" doesn't work as it wont bind to a field, but will if it's a property with applicable get/set. I just think it's a pain to go through such efforts when it's the same repetition over and over, and believe there is a shorter / more simplified method. I just don't have another mentor to learn from and know that S/O has plenty to help out.
For the current situation I'm in, requires me to only work with .Net 2.0 max... Some restrictions based on handheld devices not yet capable of running 3.0, 3.5, etc.
In C# 3 or higher, you can use auto-implemented properties:
public int MyInt { get; set; }
In VS2010 & 2008 you can right click on the private field, select Refactor->Encapsulate Field.
You will still have to do it field by field, but it has got some smarts in it (with regards to choosing a publicly viewable name), and you can do it all with no typing.
Follow up: i see that the answer from Josh M shows you the keyboard shortcut to do the same thing.
Instead of using fields use properties to begin with:
public int MyInt { get; set }
public DateTime SomeDate { get; set; }
Try CTRL+R+E while on the field.
See more great shortcuts in this blog post.
I don't think there is any shortcut to create fields (other than manually typing it), though it is possible to create properties for "existing" fields in a class. So, in this case you will have write 50 fields, and then you can ask VS to auto-generate the properties for you. Even better if you have Resharper (i think, alt+insert will do the job).
If you have a list of columns/fields and their type, then you can use CodeDom. And then auto-generate the whole class, with all the fields and properties based on the list of columns you have provided.
You said you're stuck with .NET 2.0. Please note that you can use some C# 3.0 features but still target .NET 2.0 Framework. So as long as you use VS2008 and set the target to .NET 2.0 you can use autoprops (and a few other cool features of C# 3.0). Here is a bunch of links on this topic:
http://weblogs.asp.net/shahar/archive/2008/01/23/use-c-3-features-from-c-2-and-net-2-0-code.aspx
http://www.danielmoth.com/Blog/Using-Extension-Methods-In-Fx-20-Projects.aspx
http://www.developer.com/net/csharp/article.php/3598381/The-New-Lambda-Expressions-Feature-in-C-30.htm
type propfull then press TAB twice

Checking string format at compile time in C#

In my code there are several strings which are used as keys to access resources. These keys have a specific format, e.g.
string key = "ABC123";
Currently, all these keys are stored as strings, but I'd like to make things more robust and type-safe. Ideally, I'd like to check the strings are in the correct format at compile time.
The next stage is to create a ResourceKey class that is initialised from a string. I can then check the format of the string at runtime, e.g.
ResourceKey key = "ABC123";
where ResourceKey is defined as:
using System.Diagnostics;
using System.Text.RegularExpressions;
class ResourceKey
{
public string Key { get; set; }
public static implicit operator ResourceKey (string s)
{
Debug.Assert(Regex.IsMatch(s, #"^[A-Z]{3}[0-9]{3}$"));
return new ResourceKey () { Key = s };
}
}
What I'd really like to do is to have a sort of compile-time assert so that the program fails to build if anyone tries to use an invalid key. e.g.
ResourceKey k1 = "ABC123"; // compiles
ResourceKey k2 = "DEF456"; // compiles
ResourceKey k3 = "hello world"; // error at compile time
Is there any way to achieve this?
Thanks
You could check the values with a unit test. One of my co-workers had to do something similar to this in a project where we needed to ensure that all classes in a certain namespace had certain attributes applied to them.
Run the unit tests with your build (you do that anyways right? :) or as part of an integration build. This will keep your source cleaner as well as you won't have to introduce code that does assertions.
I believe that I would add a Settings class and store them there instead of creating a new type. The Settings class can be backed by an application configuration file that will make them easier to change via configuration file changes if needed. If you don't specify them in the configuration file, though, it will use the values you set as defaults.
I'd also go the unit test route. You'll need to use the InternalsVisibleTo attribute in your Assembly.cs file since I don't think that Settings can be used outside the project if you don't.
Do you really want these keys hardcoded into your app? Wouldn't it be better to have them in a config file? Then if there are any problems post compile, it's simply a runtime configuration issue.
AdamRalph has a point but the counter point also works, if you get it right at compile time, you will never have run-time config issues (assuming the correct values can't change)
Outside that, C#'s compile time abilities are absolute Junk. Their is next to nothing that can be done at compile time. The best available I known of is the template where clause. If I had to guess, I'd say that this is a intentional design choice by Anders Hejlsberg as it seems to match with the rest of the language
Andrew Hare's point about unittests + reflection is about as good as I'd expect. A co worker of mine uses that to test that any class that could be used in a particular cases correctly implemented some protocol.
If the keys are named according to the same rules as C# identifiers, or perhaps even more limiting, and known and finite, you could use an enum:
public enum ResourceKeys
{
ABC123,
DEF456
}

Categories

Resources