.NET Micro - Common Extensions Library

Hi,

The first release of the [italic]NetMf Common Extensions [/italic] library is now available!

Functionality includes:
[ulist]

  • StringBuilder implementation
  • string.Replace extension method
  • String.Format implementation (see StringUtility class)
  • TryParseInt (Long/Short etc) (see Parse class)
    [/ulist]

It’s full open source with MIT license, so you can do what you want with it commercially and non-commercially.

Please take a look at the below link and feel free to suggest any additions / issues found!

http://netmfcommonext.codeplex.com/

Cheers,

Ross

Are they written in managed code?

that looks like the kind of things we need, maybe the micro.net people will take a hint.

That’s very good work :clap:

I have a question, though : since we’re sparse on memory usage, wouldn’t such assemblies eat up too much of such a precious commodity after some time (when more methods are added) ?

Why? The compiler is only going to put onto the micro-controller those things you use, not every extension in a library. (Unless my understanding of the system is flawed.)

Memory and deployment footprints are two of the biggest issues the .Net Micro Framework team will have. They have to balance the ability to deploy onto very low powered devices while providing enough core functionality for practical usage of the framework.

I think they have done a great job of that balance so far, and don’t necessarily think methods such as string.Replace belong in the core libraries, a lot of embedded projects just don’t need it, so would unnecessary increase it’s deployment size. They have however provided enough core methods for the [italic]concept [/italic]of functionality such as string replace to be implemented as needed by developers. Implementing the [italic]IFormattable [/italic]on primitive types would have been nice though…

One thing I am very conscious of is to no bloat this ‘core’ extensions library. Functionality will be added as long as it can be justified that developers would actually use it.

As with everything embedded, each developer will need to evaluate the footprint of the library with the potential increases in productivity, and reduced code complexity.

I agree its a trade off, but some things are a pain and can be too slow in managed code eg BitConverter.ToString( byte[] )

Bitconverter is one of those library functions that is really needed in the embedded world. An optimised version in native code would really go a long way to making the .netmf more user friendly. Perhaps GHI could look into adding this in a future build of their firmware. Even a subset of the bitconverter class with the ‘type<->byte array’ conversion would be awesome, no need for the string conversion because it’s replicated elsewhere in the framework.

Jeff_Birt,

Even if you use only one method from the extensions library you still need the whole assembly on the device.

Cheers,
Valentin

[quote]Even if you use only one method from the extensions library you still need the whole assembly on the device.
[/quote]

I’m not sure that is the case. If I add a precompiled assembly, like one from GHI then yes the whole thing is part of what is sent to the device. I don’t think for source level code this is the case though. Maybe one of the guys from GHI will jump in here and clarify.

Visual Studio loads whole assemblies on the device even if you are using one method from it.

OK, but what is an ‘assembly’? A single file, a class, a namespace?

In this case, the assembly is the .dll file that users must reference.

I suspect that this is why GHI gives you their drivers in C# source code, as it allows you to only add the class that you need, instead of every device they support. I think that the common extensions library can be very useful if used the same way, allowing you to pick and choose the helper functions that you need. Working with the individual source files does make it more difficult to explain and update, but with proper instructions it could still be relatively painless for those less familiar with the Visual Studio environment.

Personally, if I have a code file that I want to include in multiple projects, I put the file in central “Library” folder, and then I add it to the project using the “Add as link” function in the “Add Existing Item” dialog box. This ensures that changes I make to the code will be included in any of the projects using the link (including overwriting the file with a new downloaded version).

[quote]In this case, the assembly is the .dll file that users must reference.

I suspect that this is why GHI gives you their drivers in C# source code, as it allows you to only add the class that you need, instead of every device they support. I think that the common extensions library can be very useful if used the same way, allowing you to pick and choose the helper functions that you need.[/quote]

That was my original point. If you just reference the assembly, then you get the whole assembly. Same as adding a dll to a desktop app. However if you add the source to your project you should not suffer this same penalty.

I apologize, when I the thread the first time I did not get that impression. The codeplex page makes no mention of adding the source files instead of referencing a dll, and so I assumed you’re comments were along those same lines. I could be mis-interpreting ross2’s intentions as well. Either way, it should be clearly stated that simply adding a large library in the form of an assembly would have a significant memory impact, and that users should only add the individual source code files that they need instead (just like the warning in the beginner’s ebook).

I just realized that I should be more clear about the warning. Currently, adding the entire library should not have a significant effect unless you are already running close to the max program memory. The issue is that, as the library expands, it will consume more and more memory. It is very similar to the comments in the ebook, which suggests beginning by referencing all of the common assemblies for the sake of learning what is available and what you need to include, but warns against including unnecessary assemblies as you’re program grows. As Ross2 said earlier, you will end up having to weigh the increase in memory against the increase in utility.

As a good practice, I would recommend linking only to the source files containing code you are going to use instead of the entire library, even though the current effect will be minimal.

I made the project open sourced with general MIT license to allow the community to use the resource as they want, that includes taking copies of just the bits of source code needed. :slight_smile:

I chose to package the release as an assembly for the following reasons:
[ulist]

  • Reusability, simplicity and easy deployment and usage for people of all experiences
  • Promoting copy and paste of a code defeats the purpose of a common set of extensions. Copies will diverge in features and functionality quickly.
  • Anyone can raise issues / bugs / feature requests on it, likewise, anyone can join and help make the library better and more efficient.
  • Easy maintenance. As new releases are made, users can simply replace their existing dll with the latest release to address any issues / bugs that have been fixed.
  • Localised unit testing and development effort. (Tests written once, everyone gets benefit)
    [/ulist]

I would also point out that the assembly size is still very small so the concerns about size are a little misleading to the average reader and user of the library. To be clear, there will be no significant impact for 99.9% of the users on this forum to use the library as it stands - unless they need ultra utlra low deploymnet footprint. As previously stated, the library is intended so stay small and not get bloated with very helper method under the sun.

I will however package the source code as a separate download for the next release to allow easier picking and choosing of functionality. Please note that internal dependencies exist, for example string.Replace requires the implemented StringBuilder class.

I would still recommend referencing the assembly rather than copying the code out of it. Code duplication should be avoided (not just for this library, but as a good coding practice) unless absolutly necessary as it can create long term maintenance and divergence issues.

Afterall, why would you want to maintain a copy of code unless absolutly necessary?

“That was my original point. If you just reference the assembly, then you get the whole assembly. Same as adding a dll to a desktop app. However if you add the source to your project you should not suffer this same penalty.”

I posted on this somewhere. Based on my inspection, *all code is added the the PE file - even uncalled methods and even in Release. So unless I was not seeing things correctly, the best way to shrink is add the code your project, and Trim out any unused code manually.

So on a new project, add your favorite extention class. Create your project. Then trim out unused extention methods before release.

@ William, correct, the entire assembly will be added.

It concerns me that deployment footprint optimizations are the first thing some people seem to want to do. Unless it is needed, you are just creating more work for yourself than needed. Yes, if you NEED to shrink the size of the deployment, copy the source files you NEED directly into you own project.

This goes against just about every software development best practice there is (code duplication typically = bad code smell), but yes you can do that if you want. Not sure why you would waste your time and customers money by copying it out and re-testing it all (as you would need/should to do for a commercial release) unless absolutely necessary. Then next month when a fix comes out, you need to find the details of the fix, and incorporate that into the version that you copied out - which may be 3 or 4 versions old, and re-test everything again. Oh and you need to do that fix across all the projects you copied the code into. Yuck.

So to save a couple of KB in deployment footprint, at consultant rates, you have cost the client an additional couple of thousand dollars in effort at a minimum, added time to the delivery schedule, and given yourself a future headache since you are now the owner of the code and responsible to update it to incorporate any fixes / optimizations others, or your client finds.

Lets not forget that .NET has the concept of assemblies/libraries for a reason, to promote reuse, encapsulation and separation of concerns between components. If you copy everything into one assembly you loose those benefits and your code will become a maintenance nightmare.

I’m not saying never copy code into you own project, but it shouldn’t be the first thing you do, and you should have a (good) reason behind it. My 2c :slight_smile:

So I am going to generalize a little here. People here come from one of two camps. Sometimes from both converging here.

Embedded Code people. You have to make a small footprint as possible. Do your task as efficient as possible while taking up as little space as possible. It either works or it doesn’t. If you can’t flip the bit then it must be a hardware failure.

.NET coders use to desktop world. Space is not a care like it was in the old days since the framework itself is 35+ meg of stuff. Whats another 3 meg in dlls. Even if I only use 12k of it. Some failures are completely out of your control so you have to trap more and find the right way around issues.

Both groups have a place and each group can learn from each other. Any assembly will likely have to make compromises for both groups. It can be done with the way the assembly is made. Split it out into its important groups so you can include what only is needed. Provide the code so it can be copied into the programmers project(s). Microsoft know this that is why .NET is created from the ground for this environment. It must be compact and fast. Reusable code in the embedded world is very important and is normally used by everyone here. Just maybe not in the way of the desktop world.

If i sound biased here i am not. I have worked both sides of this coin for longer then I care to admit.