Friday, March 14, 2008

This is so not agile.

I have a namespace: EntityFrameworkContrib.PostSharp4EF.Testing.ComplexType and a testclass: ComplexTypeTest.
When I call to EntityFramework it apparently wants to log something and fails because of a 127 category name limit: Instance names used for writing to custom counters must be 127 characters or less.

This is shown in the callstack:

System.dll!System.Diagnostics.SharedPerformanceCounter.SharedPerformanceCounter(string catName, string counterName = "numberofactiveconnectionpoolgroups", string instanceName = "unittestadapterdomain_forg:_dev_efcontrib_entityframeworkcontrib.postsharp4ef_testresults_shrtrun[18]_out_entityframeworkcontrib.postsharp4ef.testing.dll[12116]", System.Diagnostics.PerformanceCounterInstanceLifetime lifetime = Process) + 0xcc bytes   

You can see I've already made a 'shrtrun' name for the tests, instead of the long generated name. That was suggested on a few forums: the name generated by the testframework is very long and can be shortened. That might help you:

Go to Test/Edit Testrun configuration
image

However, no way does that help enough on my end.
I believe I read that this was a bug that they would fix in 2008, but it's still there.

Does that mean I should shorten my namespaces? I don't really feel like it, since I believe in clear names. One of the contributors of EFContrib even suggested writing contrib as contribution!

My current workaround is a console application that tests the code that I'm working on, but I need to build out tests now.

Anybody know any real workarounds?

Friday, March 14, 2008 6:25:22 PM (Romance Standard Time, UTC+01:00)  #    Comments [1]  |  Trackback

I just finished full support for using complex types in EFContrib. I thought I'd quickly share what complex types are and how they are used in Entity Framework.

Julie Lerman blogged about Complex Types here, where she also shows how to use them. Check her post for a great example.
In Daniel Simmons' words:
Complex types “Complex types” is the Entity Framework name for value properties which have more intricate structure than scalars. The canonical example is an Address type which contains several parts (street, city, state, etc.) Complex types are somewhat like entities except that they do not have any identity of their own (they are value types). This means that a complex type instance is always a part of some other enclosing entity—it can’t stand on its own, it doesn’t have relationships, etc. In this release, the mapping scenarios for complex types are significantly limited: inheritance is not supported, complex type properties cannot be null and they can only occur in single instances, not collections.

So, a complex type can be seen as a struct, without identity.
Let's create a complex type. I will have a person table with 3 address related columns. My person object though, should have a property named 'Address' which points to a class of type Address.
The CSDL looks like this:

        <EntityType Name="Person">
          <Key>
            <PropertyRef Name="PersonID" />
          </Key>
          <Property Name="PersonID" Type="Int32" Nullable="false" />
          <Property Name="FirstName" Type="String" Nullable="false" MaxLength="50" Unicode="false" />
          <Property Name="LastName" Type="String" Nullable="false" MaxLength="50" Unicode="false" />
          <Property Name="Address" Type="Self.Address" Nullable="false" />
        </EntityType>
        <ComplexType Name="Address">
          <Property Name="City" Type="String" Nullable="false" MaxLength="50" Unicode="false" />
          <Property Name="Street" Type="String" Nullable="false" MaxLength="50" Unicode="false" />
          <Property Name="PostalCode" Type="String" Nullable="false" MaxLength="10" Unicode="false" />
</ComplexType>

Pretty clear: our Person has an address property, with a type of 'Self.Address'. Make sure it is not Nullable. The Address is defined just like you would expect. Please know that the current designer does not allow designing complextypes visually, which is why I did it in xml.

The database looks like this:

        <EntityContainer Name="dbo">
          <EntitySet Name="Person" EntityType="ComplexTypesTestModel.Store.Person" />
        </EntityContainer>
        <EntityType Name="Person">
          <Key>
            <PropertyRef Name="PersonID" />
          </Key>
          <Property Name="PersonID" Type="int" Nullable="false"  StoreGeneratedPattern="Identity" />
          <Property Name="FirstName" Type="varchar" Nullable="false" MaxLength="50" />
          <Property Name="LastName" Type="varchar" Nullable="false" MaxLength="50" />
          <Property Name="Street" Type="varchar" Nullable="false" MaxLength="50" />
          <Property Name="City" Type="varchar" Nullable="false" MaxLength="50" />
          <Property Name="PostalCode" Type="varchar" Nullable="false" MaxLength="10" />
</EntityType>

Here we see a row with all columns in it. Darned DBA's!!

To map that database description to the classes, we take a look at the C-S mapping:

          <EntitySetMapping Name="Person">
            <EntityTypeMapping TypeName="IsTypeOf(EntityFrameworkContrib.PostSharp4EF.Testing.ComplexType.Person)">
              <MappingFragment StoreEntitySet="Person">
                <ScalarProperty Name="PersonID" ColumnName="PersonID" />
                <ScalarProperty Name="FirstName" ColumnName="FirstName" />
                <ScalarProperty Name="LastName" ColumnName="LastName" />
                <ComplexProperty Name="Address">
                  <ScalarProperty Name="City" ColumnName="City"/>
                  <ScalarProperty Name="Street" ColumnName="Street"/>
                  <ScalarProperty Name="PostalCode" ColumnName="PostalCode"/>
                </ComplexProperty>
              </MappingFragment>
            </EntityTypeMapping>
</EntitySetMapping>

As you can see, the complexproperty is defined within the Person mapping. That caught me off-guard for a while.

EFContrib support

I have not checked in the source yet, but I will shortly at http://www.codeplex.com/efcontrib.
As you know, my contribution project to Entity Framework aims to help you use Entity Framework without all the generated code. You can just create your own domain model and add one attribute. The system will actually change the code to facilitate the EDM during compilation. Leaving you with a clean model.

It was actually quite difficult to implement this behind the scenes. To support normal entitytypes, I have to implement the three IPoco interfaces. But complex types are radically different. In the end, I had to alter the code I put into the setters of your properties.
I also had to somehow get hold of a list of properties in your type that are complexTypes (in this case Address). When the system injects your entitytype with a changetracker, it should notify all complex types. I could have done that with reflection, but we all know that's really slow. So I actually generate a method in your entity: 'UpdateComplexTypes(tracker)' and insert that with the correct IL to set the tracker in all the complextype-properties. So the solution is as fast as it can get, completely on par with handwritten c#. I may have to write another post on how I did it.

Our domain objects look like this:

  0 [Poco("ComplexTypesTestEntities")]
  1  public class Person
  2 {
  3   public int PersonID { get; set; }
  4   public string FirstName { get; set; }
  5   public string LastName { get; set; }
  6   public Address Address { get; set; }
  7 }
  8
  9 [Poco("ComplexTypesTestEntities")]
  10  public class Address
  11 {
  12   public string City { get; set; }
  13   public string Street { get; set; }
  14   public string PostalCode { get; set; }
  15 }
  16

Now, this code will work great:

  0    using (ComplexTypesTestEntities context = new ComplexTypesTestEntities())
  1    {
  2     // clear out database
  3     foreach (Person old in context.Person)
  4     {
  5      context.DeleteObject(old);
  6     }
  7     context.SaveChanges();
  8
  9     Person p = new Person { FirstName = "Ruurd", LastName = "Boeke" };
  10
  11     // this will set the changetracker
  12     context.AddToPerson(p);
  13
  14     Address a = new Address { City = "Rotterdam", Street = "My Street", PostalCode = "1111 VA" };
  15     p.Address = a;
  16
  17     IGetChangeTracker ctA = PostSharp.Post.Cast<Address, IGetChangeTracker>(a);
  18     Debug.Assert(ctA.GetChangeTracker() != null);
  19
  20     Address b = new Address { City = "Seattle", Street = "redmond street", PostalCode = "2222 BB" };
  21     p.Address = b;
  22     Debug.Assert(ctA.GetChangeTracker() == null);
  23
  24     IGetChangeTracker ctB = PostSharp.Post.Cast<Address, IGetChangeTracker>(b);
  25     Debug.Assert(ctB.GetChangeTracker() != null);
  26
  27     context.SaveChanges();
  28    }

You can see me casting the object to the interface I implemented on lines 17 and 24.

Friday, March 14, 2008 5:36:55 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback
 Thursday, March 13, 2008

I have not taken the time to actually play with SL yet. But I have been watching the mix sessions and are very excited about what I see. However, from what I can gather, there are a few things missing. It seems important to get this news out soon, so Microsoft can start getting some customer feedback.

For starters, there is no combobox, but I must say that this really isn't a big problem. It might even be included in the final bits, or somebody will write one for sure. No biggy.

However, Karen's video highlights some shortcomings of styling: they are write once, no application theme style like we are used to and you can not use 'based on'. That is going to be awful to say the least!

Josh Twist has an excellent post up here, where he notices the missing elementname and relativesource bindings. He doesn't use the relativesource bindings much, but I can tell you, I've had to use them to enable some great scenario's. Not having them will limit me greatly (more then missing the elementname binding).

Finally, Rob Eisenberg triggered me to write this post, mainly to point to his post here. It's a great writeup of what he is missing. It appears there are not triggers around anymore. I had already noticed that SL is coming up with a new scheme for control template authors to define the 'states' and 'elements' that need to be implemented by a template author. However great that may be, they appear to have substituted this for the trigger functionality. I can tell you, that is just terrible. Triggers are a very important part of a wpf application, and like Rob, I would implore Microsoft to reconsider this.
He also notes there is no concept of the ambient datacontext anymore. wow.. that hurts. No longer parameter-less ctors for UIElement and Frameworkelement (so, you can only inherit from Control easily) and to me one of the most important features missing: no Commands!! That means we are in a world of pain.

I must say, this has diminished my expectations of Silverlight a little bit. I really hope some of these issues are fixed before going live, because they have proven so useful in WPF.

Thursday, March 13, 2008 10:07:17 AM (Romance Standard Time, UTC+01:00)  #    Comments [3]  |  Trackback
 Tuesday, March 11, 2008

The last couple of months have been great, working on stuff that I wanted to learn more about. Now it is time to start looking for new jobs again.

I'm a freelance software engineer based in Holland (Rotterdam). If you or your company is looking for help, you can hire me for a few days/weeks/months.
Since you're reading this blog, I'm sure you know that I love WPF, WF, WCF and EF alike, so I'm a pretty rounded in the new 3.0 technologies. Apart from jobs that work with those technologies, I'm also interested in jobs where I can coach a team of developers to work agile or where I can help design your next great architecture ;-)

So, if you need a hand, email me at: work at sitechno dot com.

Tuesday, March 11, 2008 6:02:57 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback

In a previous post, I presented a PostSharp weaver that created a surrogate class for all your domain classes to help in serializing circular references (you know: Father.Children and Child.Father will cause WCF to go into a loop). The important enabler there was a List<object> that I held onto while (de)serializing. I was unhappy with the way I had solved that, so in this post, I'll just fix that.

Part of the problem was that the Server (dispatcher) has a correctly initialized OperationContext, where I could get to OperationContext.Current and do stuff. Extensions that were added in an earlier phase were no longer accessible though. A shame really.
Nicholas Allen was able to tell me how I could get a OperationContext going in the client. You can just create an OperationContext. I created a proxy class (by hand) that does this. People who love generated code are out of luck on this one, but I would recommend against using the generation tools of VS for WCF anyway.

My Proxyclass:

  0  public class PersonSvcClient : ClientBase<IPersonService>, IPersonService
  1 {
  2   public PersonSvcClient() : base ("PersonEndpoint")
  3   {
  4
  5   }
  6   #region IPersonService Members
  7
  8   public void SendPersonGraphToService(Person person)
  9   {
  10    using (new OperationContextScope(this.InnerChannel))
  11    {
  12     base.Channel.SendPersonGraphToService(person);
  13    }
  14   }
  15
  16   public Person GetPersonToClient()
  17   {
  18    using (new OperationContextScope(this.InnerChannel))
  19    {
  20     return base.Channel.GetPersonToClient();
  21    }
  22   }
  23
  24
  25   #endregion
  26 }

As you can see, I'm putting the actual calls inside a using block that just creates an operationcontextscope.

Now, if I were to subscribe to the OperationContext.Current.OperationCompleted, you would think that I had a great place to clean up. However, this event does not get thrown on the client (it works correctly on the server..). Weird.

However, now I have an OperationContext.Current in both client as server, so I can add an extension to it. Beware, I add this extension right in the surrogate. This way, it will stay around during the serialization process.

  0   public class MyContext : IExtension<OperationContext>
  1   {
  2    public static MyContext GetCurrentContext()
  3    {
  4     MyContext c = OperationContext.Current.Extensions.Find<MyContext>();
  5     if (c == null)
  6     {
  7      OperationContext.Current.Extensions.Add(c = new MyContext());
  8     }
  9
  10     return c;
  11    }
  12
  13    /// <summary>
  14    /// will keep our objects during serialization. Need to clear this before serialization (operation behavior)
  15    /// </summary>
  16    public List<object> serializationList = new List<object>();
  17
  18    /// <summary>
  19    /// will keep our objects during desrialization. Need to clear this before deserialization (operation behavior)
  20    /// </summary>
  21    /// <remarks>the key is the serialization ID that is transmitted by the </remarks>
  22    public Dictionary<int, object> deserializationList = new Dictionary<int, object>();
  23
  24    #region IExtension<OperationContext> Members
  25
  26    public void Attach(OperationContext owner)
  27    {
  28    }
  29
  30    public void Detach(OperationContext owner)
  31    {
  32    }
  33
  34    #endregion
  35   }

I've added a static GetCurrentContext method, that will add the context class if it does not exist, and return it.

Finally, now I can be sure that I have a safe place to store my lists, and it get's garbage collected properly.

Tuesday, March 11, 2008 2:19:12 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback
 Monday, March 10, 2008

I've been working on the PostSharp4EF project of EFContrib. I'm pleased to announce relationships are now supported.

This actually proved to be somewhat more work, because of all the things that are happening behind the scenes.
Entity Framework expects EdmRelationshipNavigationProperty attributes on top of the property that points to a relationship. But there is also the giant EdmRelationshipAttribute with about 8 constructor parameters.
So, I now generate these for you.

The next step was to actually get the relationship for you. I do that by removing the backing field, and replacing it with methods that access the relationshipmanager to get the relationship.

I do not want you to work directly with EF types, but you will need a way to Load relationships. So, I've introduced an interface with the appropriate Load and IsLoaded methods. Just in case you do want to hook into the EntityCollection and EntityReference, I've also supplied methods on that interface that will get you these types.

Let's look at a domain model:

  0 [Poco("SimpleRelationshipTestEntities")]
  1  public class Customer
  2 {
  3   public int CustomerID { get; set; }
  4   public string Name { get; set; }
  5
  6   public ICollection<Car> Cars { get; set; }
  7
  8   public ICollection<Order> Orders { get; set; }
  9 }
  10
  11 [Poco("SimpleRelationshipTestEntities")]
  12  public class Car
  13 {
  14   public int CarID { get; set; }
  15   public string Make { get; set; }
  16
  17   public Customer Customer { get; set; }
  18
  19 }
  20
  21 [Poco("SimpleRelationshipTestEntities")]
  22  public class Order
  23 {
  24   public int OrderID { get; set; }
  25   public int Amount { get; set; }
  26
  27   public Customer Customer { get; set; }
  28
  29
  30 }
  31

You might notice that I do not expose the concrete EF types, but instead expose ICollections.
After compilation, you can use this domainmodel like this:

  0    using (SimpleRelationshipTestEntities context = new SimpleRelationshipTestEntities())
  1    {
  2
  3     foreach (Car oldCar in context.Car)
  4     {
  5      IRelationshipLoader noLazyLoading = PostSharp.Post.Cast<Car, IRelationshipLoader>(oldCar);
  6
  7      bool wasLoaded = noLazyLoading.IsLoaded("Customer");
  8
  9      EntityReference<Customer> cu = noLazyLoading.GetRelatedReference<Customer>("Customer");
  10      cu.Load();
  11
  12      wasLoaded = noLazyLoading.IsLoaded("Customer");
  13     }
  14
  15
  16
  17     // clear out database
  18     foreach (Customer old in context.Customer)
  19     {
  20      IRelationshipLoader noLazyLoading = PostSharp.Post.Cast<Customer, IRelationshipLoader>(old);
  21
  22      bool wasLoaded = noLazyLoading.IsLoaded("Orders");
  23
  24      noLazyLoading.Load("Orders");
  25      wasLoaded = noLazyLoading.IsLoaded("Orders");
  26
  27      EntityCollection<Order> orders = noLazyLoading.GetRelatedCollection<Order>("Orders");
  28
  29      context.DeleteObject(old);
  30     }
  31     context.SaveChanges();
  32
  33
  34     Customer c = new Customer { Name = "Ruurd Boeke" };
  35     Customer c2 = new Customer { Name = "Test Customer" };
  36     Car car = new Car { Make = "Ferrari" };
  37     Order o1 = new Order { Amount = 10 };
  38     Order o2 = new Order { Amount = 20 };
  39     Order o3 = new Order { Amount = 30 };
  40
  41     car.Customer = c;
  42     car.Customer = c2// can re assign test
  43
  44     // add customer on order
  45     o1.Customer = c;
  46     o2.Customer = c;
  47     // add order on customer, new way
  48     c.Orders.Add(o3);
  49
  50
  51
  52     context.AddToCustomer(c);
  53     context.AddToCustomer(c2);
  54     context.SaveChanges();
  55    }
  56   }

Points of interest:
Line 5 casts your object to the implemented interface. This is checked at compile-time, so no worries about breaking at runtime. Using this cast, I can get to the EF types like I do at line 9 and line 27. Obviously, if you were inclined, you could place these methods on your domain classes. It does couple you to EF more though and clutters the code.

Next up are complex types. When that's done, I'm finished.

Quite pleased with this actually! ;-)

Monday, March 10, 2008 5:56:40 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback
 Wednesday, March 05, 2008

Finally, very exciting!! Scott released it at Mix 08.

Go get it here.

It seems they have released an Expression Blend version to match. Cool!
Also 2000 thousand unittests are released.

Wednesday, March 05, 2008 9:33:26 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback

the Oredev-conference posted video's of it's sessions online here.

I've just browsed the sessions that were held at this big conference, and it looks interesting. Many famous names, like Erik Meijer, Joe Duffy, Jimmy Nilsson (I read his book), Mats Helander and many others.

The conference has specific tracks: Java, .Net, Methods & Tools, Test, Project Management, Embedded System, Architecture and User Experience.

So sit back, relax, have a beer and hear great people explain important topics to you.

Just a quick tip: you can only watch the video's inside a browser. If you try to download, you will get a very small file. Open that with notepad and look for the rts: address at the very end. Copy paste the url into a good media player like VLC which knows how to deal with streams, and you will be able to watch more comfortably. I did this, because I could not scale the webversion and I had no way of scrubbing through the video.

kick it on DotNetKicks.com

Wednesday, March 05, 2008 5:48:13 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback
 Tuesday, March 04, 2008

Ever since I first got into workflow foundation, I've taken a fancy to statemachines. Once you wrap your head around them, they are a natural fit for most business processes.
The main problem everybody seems to be having with workflow though, is the versioning story. There is none!
That might be a bit harsh, you can certainly version your workflows, but to tell you the truth, you will be in a world of hurt.

The sample solution can be downloaded at the end of the post. It contains two workflows and a console application that you can play with.

Why is this updating so tough?
The workflow template is serialized to the persistence store. Any change in the workflow (adding or removing an activity) will make it impossible to deserialize the workflow again. It's serialized as a blob, so no easy transformation. I've written extensively about problems surrounding updating workflows here.

Your options pretty much exist of running side by side (which gives you a world of even more hurt, because now you have your data exchange services to version as well, and the activity library you have built) or use dynamic changes to alter the structure.
The latter being your best bet, but so much work that it takes away from the flexibility and speed of development that workflow brings to the table.

In my previous post I concluded that you would be best of just destroying your old workflow and create a new one. I stand by that! Today I was finally able to revisit the problem, and I hacked together a solution that might be interesting to people.

This solution has the following restriction:

It will only work for statemachines, that are waiting inside a state for an eventdriven activity, not inside an eventdriven activity. In other words: it is only able to update workflows that have entered a state and started waiting, not ones that have executed a few activities and is now waiting on some other input within a sequence.

Luckily for me, that is no problem at all, and it should not be a problem for you either. Statemachines should be modeled such that waiting happens when entered in a state, never inside a sequence. You can model waits inside a sequence, but I would suggest you make the delays short (minutes, as opposed to days/months/years).

My goal here is to be able to do a relatively easy update, where I have control over how I update (what to do with state etc.) and get my delays initialized to the correct timeouts again. So, in workflow1 I had a delay of 11 months, with 8 months left. When I start workflow2 and update, I need to have 8 months left again, and not 11.

Getting the delays right is the hard part.

I use some nice reflection to get to the actual type of a workflow instance. I described how to do that here. However, I was being silly. It's much easier:

            Workflow1 oldWF = workflowRuntime.GetRootActivity(instance) as Workflow1;

Made possible by these extensions:

    public static class WFExtensions
    {
        public static object GetExecutor(this WorkflowRuntime workflowRuntime, WorkflowInstance instance)
        {
            return workflowRuntime.GetType().InvokeMember(
                "Load", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, workflowRuntime,
                new object[] { instance.InstanceId, null, instance });
        }
        public static object GetRootActivity(this WorkflowRuntime workflowRuntime, WorkflowInstance instance)
        {
            object executor = workflowRuntime.GetExecutor(instance);
            return executor.GetType().GetField("rootActivity",