Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Wednesday, November 18, 2009

Strange missing feature in CSharpCodeProvider

Currently I'm developing a database application for my university study that uses NHibernate. To enable lazy loading of results it is required for all members of mapped class to be virtual, so NHibernate can create proxy that will be replaced by actual object when required. And if class has events they also must be virtual because actually this is the same fields and methods.

On the other hand I've decided to generate those classes from XML definitions. On of the reasons for this is that this classes seems to be just and a set of properties, but they need to implement INotifiyPropertyChanged. I've decided to write a code generator using System.CodeDom members and to gain some experience at working with members of this namespace. However I've found that CSharpCodeProvider doesn't generate virtual events! Despite the fact that I set the appropriate attribute the event is still normal so NHibernate couldn't generate proxy. I've search through CSharpCodeProvider with Reflector and found that in the method GenerateEvent that generates code of event there is no call of a method OutputVTableModifier that inserts "virtual" keyword. VBCodeGenerator also doesn't generate virtual events.

So I wonder whether this is an intentional decision or the bug in the current .NET framework version (I have 3.5 SP 1). Actually I wasn't determined enough to search for this in the older version of .NET.

Saturday, March 07, 2009

NonLatin symbols in MySQL

While developing my recent program in databases I found that my program on C# doesn't work correctly with onlatin chracters. It happend with recent version MySql.Data connector assembly from MySql. But there was no such problem when I've used old ByteFX.Data assembly. But old connector has some other error (at least when it works with server 5.2). After digesting a problem I found how to make my program work correctly with nonlatin characters. The solution is obvious: program must use a unicode, so here I'll show that to change in configurations of database and cliet software.
  1. Encoding of connection must be Unicode. For this in connection string add this parameter: CharSet=utf8;
  2. Encoding of database also must be Unicode. In my.cnf file following variables must be set to utf8: default-character-set and chracter-set-server
  3. However this helped me only on Linux machine, on Windows MySQL crashed after string with such prameters. So on Windows I found another possible solution: specify charset only for database: CREATE DATABASE dbName CHARACTER SET = utf8;. This solution is more flexible than previous because it affects only your database and not whole server.

Tuesday, December 30, 2008

Loading Satellite Assemblies From Custom Path

One thing that distracted me in default localization technologies in .NET was that  culture-specific folders are placed on one level with executable file. So if binary files lie in the root of application folder, as a result en-US, ru-RU and other folders are mixed with something like Data, Resources and others. Not good layout of folders.

By default .NET searchs for dependendent assemblies in directory of executable file in and in GAC. But developer can specify additional directories in exe.config file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <probing privatePath="./Lib" />
        </assemblyBinding>
    </runtime>
</configuration>

There are some limitations: no absolute paths and no walking up the directory tree ( ..\Lib will not work). Recently I've tested this for satellite assemblies and I have found that frameowork searchs in provided directories for satellite assemblies. So I can make something like that:

Main.exe
Main.exe.config
I18N\en-US\Main.resources.dll
I18N\ru-RU\Main.resources.dll

However as I've mentioned if I move Main.exe to Bin directory this will not work correctly. I know 2 possible ways to override this:
  1. codeBase element in config file, but it requires absolute path
  2. Adding handler for ApplicationDomain.AssemblyResolve event which will return whatever you want.

Friday, December 26, 2008

WPF Application Doesn't Load Resources in IDE

While working with WPF application I've experienced a problem: library assembly requests resource from System.Windows.Application which is defined in executable assembly in XAML file and this resource isn't loaded while I work in IDE! If I debug application all works fine, but XAML designer doesn't load resource, library method fails and window isn't rendered in designer. Of course I still can work with pure XAML and mostly I do so, but I prefer to have an ability to quickly watch results of my work in designer. So to workaround this problem I changed failed method so he will return not fully correct value which will not depend on application resources.

Monday, August 25, 2008

Enum as a ComboBox.ItemSource in WPF

Currently I'm working on my first project with WPF and study it on a practice. In this short article I want to give example how in XAML make ComboBox list values (or names) of enum.

ItemsControl.ItemsSource uses IEnumerable as source of items to list in ItemsControl (which ComboBox is derived from). In C# you can do this very simply:

comboBox.ItemsSource = Enum.GetNames( typeof( Dock ) );

You can do the same using only XAML:

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="ItemsSource test" Height="70" Width="150" WindowStyle="ToolWindow">
<Window.Resources>
<ObjectDataProvider x:Key="DockNames"
MethodName="GetNames" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type Type="{x:Type Dock}" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid>
<ComboBox Margin="5" Width="120" Height="23" Name="comboBox"
HorizontalAlignment="Left" VerticalAlignment="Top"
ItemsSource="{Binding Source={StaticResource DockNames}}"
SelectedIndex="0">
</ComboBox>
</Grid>
</Window>

In this sample ObjectDataProvider is a wrapper for a method call and to assign this data provider to ItemsSource binding is used. As you can see XAML version of requires more lines of code. But it is usefull if development team strictly follows the rule that interface view must be defined in XAML without code on C#.

Monday, July 14, 2008

Simple (and funny in some way) recursy in C#

While recent work with reflections in .NET I found a funny way for recursion:

using System;

namespace ConsoleApplication1 {

class Program {

static void Main(string[] args) {
Program p =
new Program();
Console.WriteLine(p.Property);
}

public String Property {
get {
Console.WriteLine(
"Getting property, counter {0}.", counter++);
return (String)this.GetType().
GetProperty(
"Property").GetValue(this, null);
}
}
int counter = 0;
}

}
Getter of property gets PropertyInfo of itself and calls GetValue method.

Wednesday, December 05, 2007

Visual Studio 2008

In the end of November MS released the new version of its IDE Visual Studio 2008. I've used Beta version already. It that post I've written that first impression was that is is very buggy, and later practice showed that there are some mistakes. I usually had some problems with Intellisense and IDE crashed. I have to note that I used Professional Edition.

Now I'm using Express Edition. I'm not so rich to buy IDE now, so use free edition. Of course it's not so functional as Pro version and for each language (C#, C++, VB.NET, Web development) there is it's own IDE. However I'm currently programming only on C# so this is not a big problem for me. Visual Studio is rather comfortable IDE (especially comparing to Turbo C we have in unversity :(. The problem is that it can't be used for editing all types of files I need with syntax coloring. So for editing files such as Nullsoft installation scripts, Python files and others I use PSPad. But for C# Visual Studio is much more preferable because autocompletion, Intellisense and many other small but very useful features.

One interesting note about Visual Studio: with IDE many other components are installed (SQL Server Compact, etc.). But uninstalling them is a manual operation. Not rather comfortable.

I have to say that Visual Studio is one of my favorite MS products and I haven't a lot of complains about it.

Thursday, November 01, 2007

My Own Scripting Language for .NET Framework

I've wrote about dynamic languages and that they are good at combining already written components into full application. As I'm programming at C# now which isn't very laconic and simple language I have an idea of scripting language for .NET Framework. There are a lot of languages ported on it, among them: Python, Ruby, etc. But I still has an idea of implementing my own interpreter. It will be very useful in implementation of DSLs for my own applications. At least if I wouldn't be .NET programmer I'll get a lot of experience in developing interpreters. It's not a simple task but very interesting and useful.

Currently I'm working on library of common classes for .NET. I wasn't pleased with standard implementation because I didn't find a way for customization, e.g. changing path of saving configuration file.

Also there is a LogFile class, which implements DebugListener abstract class. I attach it to Debug to write down messages about errors.

P.S. I've passed all laboratory works in programming and think now I'll have more time for non-study programming.

Wednesday, October 24, 2007

My Example of Factory Method Pattern

I found rather useful reading a "Design Patterns" and found some examples of those patterns in programs I've written or read. And some days ago I've used one of the patterns - Factory Method.

What was the case? I've wrote two types of collections for C#: Vector (casual array) and LList (Linked List). They have the same interface ISequence and sane base abstract class SequenceBase which implements most of operations leaving virtual only basic operations, such as Insert, Remove, etc. And I wanted to have tests for all methods for both implementations. I'm using NUnit, and I didn't wanted to have two test classes with identical content, in except of operation new. So what I've made:
  1. Wrote an abstract class with all test cases (e.g. SequenceTester). All test methods have their Test tag.
  2. Class defines an abstract method Instance, which returns an object of tested interface, ISequence in my case.
  3. In all test methods I use Instance instead of operation new.
  4. For each tested class I define a test class derived from SequenceTester. In have to implement only Instance method that returns an instance of tested class and tests for an implementation of interface is ready!
The only thing I need to care is to add a test class for each implementation. Rather easy? ;) And moreover generation of concrete test classes could be delegated to special tool run before test process and building of tests.

Whats is good, as I think, is that such an approach could be used to test all implementations of each interface. Write tests for interface in abstract class, write tool to search implementations and generate required test classes and you can be sure that this interface work well in all cases, or in other case you get a pointer(s) to error(s).

I think I'll try to use this approach in my practice and write such a tool to make concrete classes for tests of interface implementations.

Off-topic: While writing this post I again faced the question: why implement array and linked list with same interface? The difference in the way they work make some operations unsuitable for one type while be good for other, so why include these operation in common interface? I think it's the question worth its own article, so I'll explore this question in future.

Sunday, October 07, 2007

Implementing custom tool in Visual Studio 2008

I've recently wrote about making tool to generate C# code. We may say that are macros for C# (it fact it is only one defined macro — for fields and properties).

And how to implement this tool? There can be two ways: write tool on scripting language that generates C# code file and is called before compilation. Another way is to use ability of Visual Studio to switch user custom tool for generating files. Firstly I've implemented tool by first way on Python and now I want to make a custom tool for Visual Studio written on C#. But how to plug custom tools in Visual Studio? Now I've got an answer, though I've spent much time to understand this.

Firstly, to develop plug-ins for Visual Studio it is needed to download Visual Studio SDK (for appropriate version of Visual Studio). I have to say that after installing it my Visual Studio 2008 Beta 2 became very unstable: IntelliSense regularly produces errors which crashes the whole Visual Studio.

After that Visual Studio will add templates of its addins. That's a base for future project (although may be addin can be created without all that stuff that is in template).

To make custom tool for generation of files the one must implement IVsSingleFileGenerator interface. I've spent a lot of time trying to make this and fails mainly because if this problem: in some places of documentation it is said that function generate gets a parameter of type out IntPtr[], in some it is said that it is out IntPtr and in fact interface has just IntPtr[]. Not any out! So how should I return value of pointer? Ok, I'm not a great specialist in .NET and arrays a sent be reference. Even if this is not a problem why there is an array not one pointer? Another outgoing parameter of function on exit must contain an amount of bytes in that array but how this will help if I'll allocate a different amount of bytes in different pointers in array. However I don't see a use for an array and just tried to allocate it and use only index 0. But this doesn't helped me and I failed in implementing that interface. May be that a bug in SDK and interface must have out IntPtr[]? Don't know I'm not a guru in Visual Studio.

I've failed to get a proper answer from MSDN documentation and my attempts so I've googled this problem.I've found some solutions but the most notable part is that in Visual Studio 2003 there was an abstract class which covered that horrible interface under much more comfortable interface. However "evil" Microsoft removed that class from version 2005. But good guys placed dll with it in Internet, i.e. here. So It's needed to implement function GetCode from that class and tool is ready to use!

However it is still needed to plug it in Visual Studio. First step is to register it as a package. This can be done by tool regpkg. It is placed in <%MVS SDK Dir%>\Tools\Bin\ directory. Just run it with a path to our compiled tool as a argument. This step can also be done manually,

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\<%MVSVersion%>\CLSID\{<%guid%>}]
@=<%Tool name%>
"InprocServer32"="C:\\WINDOWS\\system32\\mscoree.dll"
"ThreadingModel"="Both" "Class"=<%class name of tool%>
"Assembly"="<%asm name%>, Version=<%asm version%>, Culture=<%culture%>, PublicKeyToken=<%public key%>"


As you may noticed custom tool must be in GAC. May be there is a way to keep it somewhere else but I don't know.

What is next? Registered custom tool need to be registered as a generator. In registry dir of Visual Studio there is a directory Generators. There is some dirs in it: FA... is a C#, 16... is a VB.NET. It is needed to register tool for each language separately. In directory of proper language add directory with name of your tool, i.e. for my tool called CSGen:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Generators\{fae04ec1-301f-11d3-bf4b-00c04f79efbc}\CSGen] @="CSGen tool to generate code on C#"
"CLSID"="{<%clsid registed in \CLSID\%>}"
"GeneratesDesignTimeSource"=dword:00000001


After that start Visual Studio choose file in project and in properties type name of custom tool. After each save file will be regenerated. It is also can be forced manually: right-click on file in Solution Explorer and "Run custom tool".

These articles with examples could be helpful (I'm not a good explainer, just learning):

Wednesday, October 03, 2007

Tool to generate code on C#

While reading in "Pragmatic programmer" chapter about automation I've formed an idea of creating a tool for C# which will reduce amount of manual typed code and as a result help to avoid errors.

Now I've got only one idea for this tool, but maybe in future I've got some more. So that's an idea? In many cases I've needed to create a public property and private field to keep value of property. In some cases I also need to create an event which will happen when value of property is changed. It is a lot of similar typing work. Of course it can be made easier by Visual Studio snippets and I've used them, but this still leaves much work during maintenance:
  • while renaming I need to rename field, property and if exists event. Of course refactoring capabilities of IDE free me from necessity to search of uses of this names, but I still have to rename 2-3 elements of class.
  • I have to have separate snippets to cases when I don't want to have an event, or want to make set private. Also when this details are changed during refactoring it is needed to make them by hand.
  • It takes a lot of locs. If it be possible to write all of necessary data in one line it will be much better to read and understand.
So I've written a tool on Python which eliminates these problems. It parsers file and search for special marker in commentaries. When it founds it, tool reads options and replaces this code with a valid C# code. Lets look at example:

public event EventHandler DoubleFieldChanged;
private double _doubleField;
public double DoubleField {
get { return _doubleField; }
set {
this._doubleField = value;
if ( this.DoubleFieldChanged != null )
this.DoubleFieldChanged(this, new EventArgs());
}
}

Is an original code on C#. Most of these tokens are just speaking what is already said by others. It can be replaced by just one line:

    // @Field double Double Field

Note that name is written not as identifier but as a casual name. My tool automatically forms valid identifiers for field, property and event. And if field is renamed all identifiers are changed by program not by programmer. Moreover 10 lines are replaced by 1! Of course not in all cases such tool can give so good results.

Moreover my tool already can read some parameters of created field. Want to have set be private? No problem:

    // @Field double Double Field( private set )

And tool will make the rest. The same way I can command it not to generate event (and of course not to call it!). Of course both options can be combined together.

My tool (arrrhhh... I call it csgen!) also provides basic customization to format of output identifiers. But now csgen couldn't make complex generations. In some cases it is needed to manually create all of this code on C#.

Though I nave some ideas of making csgen more useful. For example if set needs to check incoming value. Just add to description something like: // @Field: set requires Checker.IsValid(value) and throw an ArgumentException in case of invalid value. To implement this feature I csgen will need all text after requires and paste it into if condition. Moreover in such way can be implemented some other features.

But there will be a problem: compiler will point to errors in generated code and show its line numbers. So programmer have to read faulty code in generated file and then match it with content of original file and fix errors there. Not very good.

However to finish on good news I have to say that tried to implement this feature as a 'custom tool' in Visual Studio. I'll soon write post about it, but I can say that succeeded to write module that returns IDE text and it works with it!

Friday, August 24, 2007

My recent .NET programming

A month ago I was writing about bugs in Visual Studio 2008 Beta 2. All in all I've escaped trouble and for a month I was using it. Professional edition to be exact. Of course when the Beta will expire I'll be forced to move to free Express Edition. And know I'm studying .NET and C#.

Book of Andrew Troelsen is almost at the end: only 2.5 chapter remain for me. They are all about ASP.NET and Web.

Moreover my text editor became much better. Though it is still have not vast functionality. I have an idea of turning it into IDE for any computer language (Python and Ruby are first candidates), but as I think this is not the matter of near future.

Programming for .NET on C# was good and effective, though there are some things that I don't like in it and want to replace them by equivalents from scripting languages. Of course that relates to new computer language. I made it to parse arithmetic expressions with integer numbers and make *.exe file that performs all these calculations. Not very much and I've stopped on trying to implement print function. The problem is not in the implementing particular built-in function but much more in whole mechanism of implementing functions. I've decided not to make thinking about it, but to take a pause. Though this idea firmly seats in my head so I think I'll return to it after gaining some experience. And moreover I'll need some time to feel pace of study on second year!

Furthermore now I'm working on .NET library to create diagrams. I've wanted to have one to make colourful diagrams from my data which is output from scripts, not in Excel format. For now it already can make proper diagram! So in future I need to add much more customisation to it.

Moreover, I've tried Ruby. It looks rather interesting and has simple solutions for problems which I've already faced in other languages(and not yet faced). I'll study it more deeply and try use it in my projects. For now if I need to make some routine tasks I prefer Python. Hope in near future I'll write more on computer languages.

— Buy! :)

Monday, July 09, 2007

Egnoly Text Editor

For about one year ago, I bought my first book about programming — it was "C++ How to Program" by H.M.Deitel and P.J.Deitel. I've read 4th edition and now they are preparing to publish 6th edition. I think that's rather a good book for starter, all in all I've learned much from it, in despite of that it is about C++ — not very easy language. For that year I've learned basics of Python, Perl, Java, Ada, C#, Visual Basic and in university I've studied Turbo Pascal for one year. All of I've programmed were console applications. The only exception was working with Microsoft Access on courses were I used VB for modules, but that was not "normal" programming of GUI — all in all it is Access not Visual Studio. And after the year of programming I've changed the situation.

Now I'm working in Visual Studio on my first "normal" GUI application — text editor which I've called Egnoly. I'm writing it on C#. Yesterday I finished first version of it (0.0.1). It can open and save file. Plus built in Windows Forms TextBox class abilities of cut/copy/paste. Not very much. But it works! Moreover development GUI apps is rather unfamiliar task for me, so Egnoly hasn't any tests written and strong system of exceptions. Furthermore I don't know C# well.
To resolve the last problem I've bought Andrew Troelsen "Pro C# 2005 and the .NET 2.0 Platform, Third Edition". I think after reading it I'll be comfortable with developing GUI, e.g. modifying classes from System.Windows.Forms (as a understand that what I need to make a color syntax highlight).

So I've started my way to become a GUI wizard :) For now Egnoly is only a program to develop my programming skills from bad to "something better" :), bit what it will be in future?.. Time will show... :)

Wednesday, June 13, 2007

up

I'm writing an application to evaluate numeric expressions and in future I want to expand it to perform much more complex operations, even to programming language.

0.0.1a1 - that is number of first version that was doing something. In fact it takes from standard input binary operation with integer values, calculates result and prints it.

Now i'm working on refactoring object model in this application. At first I've made a template which was a wrap to existent classes and types. But than I've understand that it will be much better to create exact classes for types, so instead of Value<> I'll have class IntType. Moreover I will soon add an ability to parse multiple binary expressions from input and (of course) print version number if there is specified flag --version. After that I plan to add parsing of expressions of any number of operands. And after that... my plans are not very clear...