DirectoryEntry Enabled

August 27, 2008

I need to check whether an account in the active directory was enabled.

After some searching, I came to understand that the enabled feature is not only for User but for every node in the active directory. That means every DirectoryEntry instance.

Here is how you check if it is enabled

public const string        AccountControl="userAccountControl";
public const int EnabledFlag= 0x2;
static bool IsEnabled(DirectoryEntry de)
{
  return (((int)
  de.Properties[AccountControl].Value)
  & EnabledFlag) == 0;
}
 

Active Directory Connection

August 27, 2008

Recently I have been asked to query our Active Directory.

I really believe that the documentation is really poor about the connection, and what the errors mean.

After all the problems, and the never ending errors that I could not comprehend, I stumped upon a post that said LDAP prefix must be Uppercase.

A few thing about the connection string, since I am writing this post.

I do not know of Active Directory administration so, what I will write here is my experience in this situation and hopefully someone will benefit.

At my company we have a domain which from windows we see as DomainName. There are a few places in windows, that I had seen a local suffix in out domain. I do not know what this means. Our domain is located on machine called SERV1 for example with IP 192.168.0.1.

In case I’m not entirely clear about my environment, let me specify that my computer registers on the network as DomainName\PCName and my Domain Account is DomainName\sarafian.

The only valid connection string that works for us is LDAP://192.168.0.1/dc=DomainName,dc=local

Anything else just doesn’t.

Here is the creation of root DirectoryEntry

private static DirectoryEntry GetRoot()
{
    DirectoryEntry de = new DirectoryEntry(
      "LDAP://192.168.0.1/dc=DomainName,dc=local"
     , null, null, AuthenticationTypes.Secure);
    return de;
}

Hopefully someone will benefit and won’t get frustrated as I did, with all the combinations and their incomprehensive error messages.

 


How to debug a WCF service

June 28, 2008

Introduction

WCF default debugging does not support edit and continue features, as I have said in my blog post

Background

In that post I said that there is an easy way to do it, but I didn’t give any code. So this article is about how to it. The reason I wrote this article, is because a fellow member wrote a useful article about wcf, and in tip1 he suggested using a console application.

My scenario for wcf service consuming and debugging is a Client Server application. I believe my solution can apply and for other scenarios.

How to do it

You need this class DebugServiceHost

internal class DebugServiceHost:IDisposable
{
    private static string serviceExecuteTypeName = "ExecutionService.ServiceExecute, ServiceSide.ExecutionService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
    private static string iServiceExecuteTypeName = "ExecutionService.IServiceExecute, ServiceSide.ExecutionService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
public static string Address = @"http://localhost:9999/ExecutionService/ServiceExecute/";
    public static Binding Binding = new WSHttpBinding();

    static DebugServiceHost()
    {
        isEnabled = Type.GetType(serviceExecuteTypeName) != null;
    }
    public DebugServiceHost()
    {
        Type serviceType = Type.GetType(serviceExecuteTypeName);
        Type iServiceType = Type.GetType(iServiceExecuteTypeName);
        this.debugHost = new ServiceHost(serviceType);

        this.debugHost.AddServiceEndpoint(iServiceType, Binding, Address);
        this.debugHost.Open();
    }

    private System.ServiceModel.ServiceHost debugHost;

    private static bool isEnabled = false;
    public static bool IsEnabled
    {
        get { return isEnabled; }
    }

    #region IDisposable Members
    private bool disposed = false;
    public void Dispose()
    {
        if (this.disposed)
        {
            return;
        }
        this.debugHost.Close();
        GC.SuppressFinalize(this);
    }

    #endregion
}

where ServiceSide.ExecutionService.ServiceExecute is the namespace of the wcf service and ServiceSide.ExecutionService the assembly containing it.

Using the code

I use a provider class, but its up to you how to implement the above feature.

DebugServiceHost has a static property IsEnabled, which basically checks whether the service is locally located to the running client execution folder. If that is true then using an instance of the class, host the service as well, which is automatically disposed.

This a sample code from my project that consumed the true or debug hosted service.

Collapse

public static class Provider
{
    private static DebugServiceHost dbh;
    public static void CheckAndRunDebugService()
    {
        if (DebugServiceHost.IsEnabled)
        {
            dbh = new DebugServiceHost();
        }
    }
    public static string RemoteURL { get; set; }
    private static IServiceExecute iServiceExecute = null;
    private static IServiceExecute GetInterface()
    {
        if (iServiceExecute != null)
            return iServiceExecute;
        iServiceExecute = CreateClient();
        return iServiceExecute;
    }
    private static ServiceExecuteClient CreateClient()
    {
        string address = "";
        if (DebugServiceHost.IsEnabled)
        {
            address = DebugServiceHost.Address;
        }
        else
        {
            address = String.Format("{0}/Service.svc", Provider.RemoteURL);
        }
        return new ServiceExecuteReference.ServiceExecuteClient("DefaultEndPoint", address);
    }
}

where

  • IServiceExecute is the Interface created when you add the service Reference.
  • ServiceExecuteReference.ServiceExecuteClient is the client created when you add the service reference
  • DefaultEndPoint is the endpoint in my config file.

Points of Interest

At first I at the first call to the service, I create the host. But as I mentioned in my post there was problem with that implementation.

Last problem hopefully

Finally a point of interest which was my last obstacle that took me a half day to find. I had implemented a provider class for the remoting part, which if needed, fired up the service host. Everything worked just great in the test projects, but at some point I tried to extend the framework with WPF.

The trick was that at first request, through static constructor I checked if the service was required to be hosted, and did that. But this did not work when I made the call from WPF. The only error was a timeout exception. I was going crazy, and then it kicked in. Never trust completely a 3 party library.

Solution

I made three clients, one Console, one Windows one WPF and stripped down the functionality of my framework to test. On each UI Client I made the call (and raised subsequently the host) after a UI reaction. I turns out that neither Windows Forms played correctly, when for example the call is made through a button click event. When I saw that, I made the host come up before the UI part was ever initialized and guess what? It all played just fine.

I really can’t understand how this has not been mentioned.

So I refactored the code, and at the program main entry method I call Provider.CheckAndRunDebugService()

Final thing is that, you must implement a trick in order for all serverside assemblies to be found in the client execution folder when you are debugging. There are a number of ways to do achieve this mainly by using post build event or by just adding the references and deleting them when in deployment face. I use the first.

Apologies

There is not project code, because the above resides in a framework project, I have written for the company I work for.

CodeProject Article


WCF Debugging and a WCF review

June 17, 2008

A comment

At some point, people need to understand that, business applications are not like console applications. So all these comments on the net, in blogs and forums, should be a little more double checked for real life development process because they mislead other people. Especially for LINQ to SQL and WCF, I am really bored reading about how great they are and how easy they are, but the truth is that LINQ to SQL is not for applications (reason in another post) and I was one of the victims that tried to adopt it, and WCF although is great, it can also be a pain in the ass. When searching through the net, keep in mind always that Internet is not always correct as I have wrote here. I really suspect that many of the blog post although, they can be helping, are not revealing entirely the truth and the disadvantages. I have always been fun of Microsoft Technologies but there is a limit to the indirect advertisement.

Following instructions

Back to the post subject. Many of you have done what everybody on Internet says. Add a WCF Service and a Service Reference and Great, all is ready and done. Even for debug, every time I execute debug the application, a dummy Debug Host is raised and I can debug the service. All is great? No.

Questions

First of all. What if I’m not running parts of the solution that require the service. Why should I be punished with the overhead of raising the host?

Second and most serious. Has really anyone tried to debug the service, and every underlying class used by it? Has anybody tried to utilize edit and continue, among all these guys who say how great WCF is?

I tried and as you can guess from my attitude, I could not utilize Edit And Continue. When I am developing a big Application, usually there will be at least 2 layers behind the service. Should I restart the application each time? And don’t let me talk about the debug through the dummy client, when an Operation Contract of mine, will use a complex data type. It is just not possible.

So what is the solution?

Easy someone can say, but easier said than done. As you would with .Net Remoting, If the service is located in your output directory, by whatever trick in the solution, then just raise the host programmatically in an address of your choice and then tell the client to hit this address. This way you have always simulating data transferring through WCF channels (very important), and you can of coarse use the feature of Edit and Continue.

The problem is that the dummy service the solution raised keeps coming up, which is very annoying. I haven’t found a solution, mainly because in the framework I’m developing, there is a single Operation Contract handling abstract Message Types. This was another great milestone for me in WCF. I really can’t understand why they have made DataContractSerializer as complicated, and not simple as the one used in plain old fashioned remoting. Having this service in my framework, I do not have in my solution the WCF Service so , there is no penalty overhead from the Debug Host that is raised.

Last problem hopefully

Finally a point of interest which was my last obstacle that took me a half day to find. I had implemented a provider class for the remoting part, which if needed, fired up the service host. Everything worked just great in the test projects, but at some point I tried to extend the framework with WPF.

The trick was that at first request, through static constructor I checked if the service was required to be hosted, and did that. But this did not work when I made the call from WPF. The only error was a timeout exception. I was going crazy, and then it kicked in. Never trust completely a 3 party library.

Solution

I made three clients, one Console, one Windows one WPF and stripped down the functionality of my framework to test. On each UI Client I made the call (and raised subsequently the host) after a UI reaction. I turns out that neither Windows Forms played correctly, when for example the call is made through a button click event. When I saw that, I made the host come up before the UI part was ever initialized and guess what? It all played just fine.

I really can’t understand how this has not been mentioned.

Conclusion

For me WCF is good for the plumbing. It is much more complicated than .Net remoting, really hard to troubleshoot if you are doing something outside the ordinary, which are discussed in all those praising posts and articles. Maybe I haven’t studied it as much, maybe I’m missing something but if the case is true, tell me how something that is advertised as easy and all remoting-problem solving can be this hard to utilize and debug. You will say that WPF, has as much difficult learning curve but WPF is not advertised as the magic trick that the programming world was missing. Since I have read about it, everyone mentioned that it is hard and difficult to adopt, and it is not for all kinds of applications. For me WPF is the star of .NET3.

Despite all these problems I really believe in WCF, because of other great stuff that it supports.  Regarding security MS says here that

You should not use WCF Service Host to host services in a production environment, as it was not engineered for this purpose. WCF Service Host does not support the reliability, security, and manageability requirements of such an environment. Instead, use IIS since it provides superior reliability and monitoring features, and is the preferred solution for hosting services. Once development of your services is complete, you should migrate the services from WCF Service Host to IIS.

Having this in mind, I can’t stop thinking whether WCF is a great overhead on development, when .NET is remoting is a well tested solution under IIS. But choices have been made, mainly because the new technology I believe is here to stay.

Links

Same Article at code project.


Set a value to a control only in design mode

June 14, 2008

I have been working on making my project localizable. I made it using Resources just like skins but this will be another post.

The final problem I encountered was that there was no design time support to show a dummy text, in a Button for example. Everything was going well except from the design part which was not that significant for me, but as I’m the writer of the company’s new framework it might be for others.

So can you set a value to DependencyProperty of a DependencyObject only to in DesignMode?

Using a custom MarkupExtension you can. Here is the implementation

[ContentProperty("Value")]
public class  DesignTimeDummy : MarkupExtension
{
    public DesignTimeDummy()    {

    }
    public object  Value { get; set; }
    public override object  ProvideValue
          (IServiceProvider serviceProvider)
    {
        if (Helpers.Designer.InDesignMode)
        {

            return Value;

        }
        return DependencyProperty.UnsetValue;
    }

}

And this is how you can use it

<Button Style=”{DynamicResource styleName}” Content=”{CoreME:DesignTimeDummy Value=DesignContentValue}”/>

or

<Button Style="{DynamicResource cancelButtonStyle}" >
  <Button.Content>
    <CoreME:DesignTimeDummy>
      Dummy
    </CoreME:DesignTimeDummy>
  </Button.Content>
</Button>

where CoreME is an xmlns defined namespace shortcut

 


In design mode

June 14, 2008

WPF project has begun and I have been continuously finding new things. I’m very excited, mainly because what I have accomplished to today. Maybe I will write about it.

Many thanks to fellows like Josh,Karl and Sasha for the knowledge I have acquired from them since Summer 2007.

One of the things I needed, for my next post, is to know if code is running in DesignMode or not.

So here is the class I wrote

public static class Designer
{
    private static DependencyObject dummy = new DependencyObject();
    public static bool InDesignMode
    {
        get { return DesignerProperties.GetIsInDesignMode(dummy); }
    }
}


Typed Dataset <–> Linq Entities

April 21, 2008

Introduction

On my previous post I discussed about how LINQ entities to not fit the world of applications that do not have a constant access to the data source. I concluded that if there was a way to connect Linq Entities and Type Dataset, then the domain of Web Applications and N-Tier Applications could be supported by the same Bussiness Object Model and a Data Access Layer over LINQ.

Assumptions – Prerequisites

Entity and Data Table Naming

Before I continue there is a basic assumption that must be kept in mind. The Business Object Model and the Typed Dataset must be constructed by their respective designer in Visual Studio, by dragging the tables into each designer. The main reason is, that the converter I have developed, assumes that the corresponding entities in LINQ and table in the Dataset have the same name.

Relations and Foreign Key Constraints

Also every relation between entities must have the same name as that between tables in the dataset. The above are automatically (great coincidence) kept, just by using the designer.

Circular Relations and all combinations have not been tested, so I do not know whether my code supports them

Database construction From LINQ

If you wish to construct the database schema from the LINQ designer then just do so, but before creating the typed dataset, the database must be created. To do this just call

LinqTestDataContext ltdc = new LinqTestDataContext(connectionString); if (!ltdc.DatabaseExists()) { ltdc.CreateDatabase(); }

where LinqTestDataContext is the DataContext the designer has created.

Column Prerequisite

Each entity must have a version property. This is because Attach(entity,true) only works if there is such a property.

The Database Schema used for testing

The LINQ schema is name LinqTest and its dataset represantion DsLinqTest.

As seen in the picture below there is a RootElement with a unique key ID, a version property TimeStamp and two string properties.

RootElement has child relation of SubRootElement entities which also have a unique key ID, a version property TimeStamp a string property and a RootID foreign key pointing to the RootElement it belongs

image

The corresponding Dataset will be. The relation name is the same, even thought it is not showing on the above image.

image

Each of the Business Object are in a separate assembly.

DataSetEntityConvertion

This is name of the assembly that does the convention between an LINQ Business Object and a Typed Dataset assuming that the above prerequisites are met.

The assembly uses heavily reflection and generics so the understanding of the above must be at least good.

Keep in mind that since the dataset is typed, every type in the dataset is specifically named so it can be used to discover the entities it relates to.

ToDataRow

Is the part where entities are used to fill the appropriate tables in the dataset.

The entry point is the Entity2DataSet class, where TEntity is the entity type and TDataSet is the dataset type. In our case RootElement and DsLinqTest respectively.

Basically the Entity2DataSet class discovers the table that corresponds to the entity, and then calls the Entity2DataRow class which in addition takes the DataTable type discovered.

There are some helping functions that through reflection fill the row, from the entity and also find the child relations of the entity if there are any. If that is true the Entity2DataSet class is called again but this time TEntity should be SubRootElement in our case.

This side of the convention is fairly easy.

ToEntity

This case deals with converting a whole dataset to its entity. The entry class is DataSet2Entity where TDataContext is the type of our DataContext and TDataSet the type of the source Dataset. In our case LinqTestBigDataContext and DsLinqTest respectively.

The first thing that DataSet2Entity does is to find the tables have no parent relations. For each of these tables DataTable2Entity is used where in addition TDataTable and TDataRow are the types of the table and its rows.

DataTable2Entity discovers the entity type that must create for each row it has and does so by using DataRow2Entity which is supplied with the knowledge of whether it is child row or not. This is crucial because if it is child row, it must be added to the related EntitySet of its parent entity instead of the entity Table in the data context.

The trick here is to know whether the original row is Added,Modified, Deleted or unchanged which is the easy part through RowState. The hard part is what to do with it.

Added

This case is easy. Just construct the entity and add it the table or the entityset and call InsertOnSubmit.

Modified or Unmodified

Here start the problems. First we must acquire the entity it self to which we will apply the values. Accordingly to if the row is a child or not, a predicate function or expression must be constructed. This part was the most difficult.

If the row is unmodified then there will be no applying of values.

Deleted

Like in Modified the entity must be retrieved from the entitytable of the datacontext in order to call DeleteOnSubmit.

Keeping track of the changes

When a row is inserted or modified, various column values need to be updated by the auto generated ones from the database. So in every entity the PropertyChanged is captured. There with the help of a dictionary the new values are applied to the original rows. This happens after the SubmitChanges of the datacontext is used.

The rest of the DataRow2Entity finds the child rows of the row for each data relation and calls another generic version of its self.

Creating Predicate Functions and Expressions

This was the hardest part, and still there are some point that I can’t understand.

When trying to acquire an entity from the table entity of the datacontext, a simple delegate function suffices. After many attempts a managed to make the creation entirely dynamic based on the primary keys of the entity.

This is done by these two functions

private System.Func<TEntity, bool> CreatePredicateFunction(TDataRow row) { return p => (IsEqual(p, row)); } private bool IsEqual(TEntity entity, TDataRow row) { for (int i = 0; i < Cache.EntityPrimaryKeys<TEntity>.Names.Count; i++) { object columnValue = null; if (row.RowState == DataRowState.Deleted) { columnValue = row[Cache.EntityPrimaryKeys<TEntity>.Names[i], DataRowVersion.Original]; } else { columnValue = row[Cache.EntityPrimaryKeys<TEntity>.Names[i]]; } if ((bool)Cache.EntityPrimaryKeys<TEntity>.EqualMethods[i].Invoke(this.entityType.GetProperty(Cache.EntityPrimaryKeys<TEntity>.Names[i]).GetValue(entity, null), new object[] { columnValue }) == false) { return false; } } return true; }

Happy as I was that I will be able to cast the above to an Expression<System.Func<TEntity, bool>> I found out that at runtime an exception is thrown telling me that IsEqual cannot be converted or something.

I assume the Expression is something far more complicated than a delegate. So in order for this to work a CreatePredicateExpression must by supplied in every DataRow of our dataset. I did like this

public static class DsLinqTestPredicators { public static Expression<System.Func<RootElement, bool>> CreatePredicateExpression(DsLinqTest.RootElementRow row) { int idValue = row.RowState == System.Data.DataRowState.Deleted ? (int)row["ID", System.Data.DataRowVersion.Original] : row.ID; return (Expression<System.Func<RootElement, bool>>)(p => p.ID.Equals(idValue)); } public static Expression<System.Func<SubRootElement, bool>> CreatePredicateExpression(DsLinqTest.SubRootElementRow row) { int idValue = row.RowState == System.Data.DataRowState.Deleted ? (int)row["ID", System.Data.DataRowVersion.Original] : row.ID; return (Expression<System.Func<SubRootElement, bool>>)(p => p.ID.Equals(idValue)); } }

Final Words for the Converter

Extension Methods are heavily used to help making the convertion as programmatically tranparent as possible.

Using the Code

Extenders

public static classDsLinqTestExtenders
{
    public static voidInsert(thisDsLinqTest extented, objectentity)
    {
        ((DataSet)extented).Insert(entity);
    }
    public static voidInsert(thisDsLinqTest extented, object[] entities)
    {
        ((DataSet)extented).Insert(entities);
    }

public static voidToEntities(thisDsLinqTest extented, DataContext dataContext)
    {
        ((DataSet)extented).ToEntities(dataContext);

}
}

Entity2Dataset

public DsLinqTest GetDsFromID(int id) { LinqTestDataContext ltdc = new LinqTestDataContext(connectionString); RootElement re = ltdc.RootElements.Single(p => p.ID.Equals(id)); DsLinqTest ds = new DsLinqTest(); ds.Insert(re); ds.AcceptChanges(); return ds;}

DataSet2Entity

public void SaveGeneralDs(DsLinqTest dsLinqTest) { LinqTestDataContext ltdc = new LinqTestDataContext(connectionString); dsLinqTest.ToEntities(ltdc); ltdc.SubmitChanges(); }

Source Code for the above assemblies


LINQ and Client Server Applications

April 21, 2008

First of all I would like to apologize for not posting links, for various sources I acquired knowledge from, because a week has passed after reading them and I don’t remember which is which.

Last week I was doing some research for LINQ and how it could be integrated in the applications I develop for my company. There is something on the net, that always keeps bugging me and I prefer to have my own opinion. Always everything is great, but there always seems to missing the parts that things are not good.

In a few words LINQ is an ORM that ships with .NET3 and from what I have seen it is very good. Truly all the great things that have been talked about are there, and even better for me. But something that stroked odd for me, was the fact that there was no single mention about Client – Server applications or known as N-Tier.

I’m not a Web Developer. I develop Smart Client Applications where the notion of disconnected from the data source is the biggest truth.

Every example in LINQ that I had saw, assumed that my application has a direct and steady connection to the data source, exactly like a web application. That maybe true for web in many cases, but in other applications is not. I tried LINQ with just one entity and sub collection, sending it to the client and bringing it back to the server, and all hell broke loose. For just a single entity, logic should be applied on how you should attach your entity to the data context. And I didn’t get to deletion.

There are two ways to manage data in disconnected state. Either you write your own mechanism or use Datasets. I prefer the latest, and especially Typed Datasets for various reasons one of which is the version mechanism that dataset have embedded inside. So I tried to search about Datasets and LINQ and there was just a little.

So I did a little research and found out that …

First of all there are two types of LINQ. LINQ to SQL and LINQ to DataSet. Both do the exact same thing, that is to query collections ,with one huge difference. LINQ to SQL queries collections directly to your data source and LINQ to Dataset queries basically your own dataset. My biggest disappointment was when I found that in the original beta, there was a functionality that converted datasets to entities and reverse, but a developer of Microsoft in his blog, mentioned that they didn’t have the resources to implement it in the current version.

My thought is that when building a framework with business objects and a data access layer that supports its persistence wouldn’t it be great to have Entities-like objects for web and a disconnected version of them for smart clients? This would be, that SQL would be reduces significantly and both application types would utilize the same idea. The only missing link is the mechanism to convert between entities and datasets without having to write extra code.

The above missing link was what I was developing a whole week. It started as a proof of concept, but it became something that I think has great potential, because I like the idea of LINQ especially for Web Applications, which I believe will be optimized even more by Microsoft, I like typed datasets for disconnected Applications and the only thing missing was something that connected them.

This post was like an introduction for my next post, that is the converter project it self.

 

 

 


Reflection BenchMark

April 19, 2008

For a project I have been developing, over the last week, I have come to utilize a lot of reflection, generics and their combination using MakeGenericType.

So today last day, I began to optimize its performance based on my experience of reflection and the .net world. I have used a lot of reflection so I believe my performance hunches were correct.

I assumed that

  1. It is a lot quicker to have a Dictionary of Types instead of calling MakeGenericType
  2. It is a lot quicker to have a dictionary of  PropertyInfo instead of using repeatetly GetPropetyInfo
  3. It is a lot quicker to have a dictionary of  MethodInfo instead of using repeatetly GetMethodInfo
  4. It is better to create static functions that will do your work as a single function, instead of calling through reflection the constructor and then the method.

So tonight I created a Benchmarking program that proved I was right on all 4. What I didn’t expect was the great time MakeGenericType needed to execute.

In the benchmark project I have a TestType.cs without generics and a GenericType.cs with two generic parameters.Each class has a public constructor, an Execute method and a static ExecuteStatic which calls the constructor and the the Execute method.

Because the operations are pretty simple, there will be no milliseconds but average ticks.

The names consist of the following

  1. Test or Generic class
  2. With reflection or not
  3. Instantiating and calling Execute or just call static ExecuteStatic
  4. Optimized or not

So here are the results

TestStatic->7
TestInstance->7
TestReflectionStatic->21
TestReflectionInstance->33
TestReflectionStaticOptimized->16
TestReflectionInstanceOptimized->24
GenericStatic->8
GenericInstance->7
GenericReflectionStatic->41
GenericReflectionInstance->75
GenericReflectionStaticOptimized->37
GenericReflectionInstanceOptimized->67
GenericReflectionMake->32
GenericReflectionMakeOptimized->12

The above example is with just one combination of generic parameters used. When I increase the number of generic combinations the results become

TestStatic->9
TestInstance->9
TestReflectionStatic->22
TestReflectionInstance->31
TestReflectionStaticOptimized->16
TestReflectionInstanceOptimized->23
GenericStatic->8
GenericInstance->9
GenericReflectionStatic->40
GenericReflectionInstance->71
GenericReflectionStaticOptimized->37
GenericReflectionInstanceOptimized->66
GenericReflectionMake->31
GenericReflectionMakeOptimized->19

As you can see the performance weakens, probably because of the dictionary and its long keys. String manipulation in .NET is not one of its strongest features.

Another thing is that in my classes, there is only one method, so minor as the difference in optimization as it may seem, keep in mind that the more methods you have in a type the slower GetMethodInfo executes.

In my benchmark I didn’t implement test about properties but I firmly believe that they will not have any difference from methods.

There is no much code in the post, because the optimization is pretty forward. Just reuse Type and MethodInfo as much as possible.

For example the not optimized way is

public static void TestReflectionInstance() { Type type = typeof(TestType); object tt = type.GetConstructor(new Type[] { }).Invoke(null); type.GetMethod(“Execute”).Invoke(tt, null); Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < iterations; i++) { type = typeof(TestType); tt = type.GetConstructor(new Type[] { }).Invoke(null); type.GetMethod(“Execute”).Invoke(tt, null); } sw.Stop(); if (Write) Console.WriteLine(“TestReflectionInstance ” + sw.ElapsedTicks.ToString()); times["TestReflectionInstance"] += sw.ElapsedTicks; }

and the optimized way is

public static void TestReflectionInstanceOptimized() { Type type = typeof(TestType); ConstructorInfo ci = type.GetConstructor(new Type[] { }); object tt = ci.Invoke(null); MethodInfo mi = type.GetMethod(“Execute”); mi.Invoke(tt, null); Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < iterations; i++) { tt = ci.Invoke(null); mi.Invoke(tt, null); //type.GetMethod(“Execute”).Invoke(tt, null); } sw.Stop(); if (Write) Console.WriteLine(“TestReflectionInstanceOptimized ” + sw.ElapsedTicks.ToString()); times["TestReflectionInstanceOptimized"] += sw.ElapsedTicks; }

My belief is that if you optimize well you code when using reflection, then the performance penalty is not so great but the advantages are many times more significant. I believe this must have been taken into account, when Microsoft developed WPF, WWF and LINQ.

CodeProject Article

The next day while I was out in the sun some thoughts came to me that made me modify the makegeneric comparicon

The Generic Benchmarking is not fair. The practical dilemma is that at any single point of execution is it better to call MakeGenericType for a generic type or to find the type form a variety of pre made types from a dictionary.

So I ran the test using the below codes

Type ii = type.MakeGenericType(new Type[] { typeof(int), typeof(int) });

and the optimized version

Type ii = makedTypes[type.FullName + "|int|int"];

and the results where which

GenericReflectionMake->26 GenericReflectionMakeOptimized->9

This shows that having pre made generic types in a sort of list is far much quicker than calling MakeGenericType

 


Creating Template Items that have nested appearance in the Solution Explorer

January 25, 2008

In a previous post of mine I mentioned the lack of being to select some items in the solution explorer and making them nested.

I believe this to be serious functionality for the Visual Studio especially for large projects using partial classes.

Finally I found how is done programmatically and not only that I implemented it on a Custom Project Item Template.

Being my blog not all that known for obvious reasons, I have decided to post all the knowledge in CodeProject. The article is this and I hope you find useful.