Thursday, December 30, 2010

WCF and ECO

I have been debugging the Remote persistence we use for ECO6 – this uses WCF. It was Jonas that started this work and he did a fine job – but we have a few gotchas that I want to get documented here.

If you build your own server (Remote persistence server for ECO), either as WindowsService or as a WinForm application (both available from the ECO VS Wizard) we use the WCF class ServiceHost.

In this ServiceHost we set some parameters – like what binding to use and so on. During the beta-phase of ECO6 it became apparent that we also needed to set a lot of other values like MaxReceivedMessageSize and MaxBufferPoolSize etc on the Binding object.

That code came to look like this:

BasicHttpBinding binding = new BasicHttpBinding();
binding.MaxReceivedMessageSize = maxReceivedMessageSize;
binding.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
binding.MaxBufferSize = int.MaxValue;
binding.MaxBufferPoolSize = 0; 
Uri address = new Uri(uri);
ServiceHost svc = new ServiceHost(t, address);
svc.AddServiceEndpoint(typeof(IPersistenceMapperWCF), binding, address);

The gotcha with this is that if you host your Remote persistence server in IIS – we do NOT use the ServiceHost because then IIS IS provides the ServiceHost for us.

So in this case we need to tune up the MaxReceivedMessageSize and MaxBufferPoolSize etc some other way : web.config.

So in your IIS hosted Remote Persistent Server you need to add something like this to your web.config:

<system.serviceModel>
  <services>
    <service name="Frako.Emvis.PServerWebService.EmvisPMPWCF" behaviorConfiguration="TheBehavior">
 
      <endpoint address=""
                binding="basicHttpBinding"
                bindingConfiguration="TheBindingConfiguration"
                contract="Eco.Wcf.Common.IPersistenceMapperWCF"  />  
 
    </service>
  </services>
  
  
  <bindings>      
    <basicHttpBinding>
      <binding name="TheBindingConfiguration"              
             maxReceivedMessageSize="104857600">
        <readerQuotas maxStringContentLength="104857600"/>
      </binding>
    </basicHttpBinding>
  </bindings>
  
  <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
      <behaviors>
          <serviceBehaviors>
              <behavior name="TheBehavior">
          
        <serviceDebug includeExceptionDetailInFaults="true" />
        <dataContractSerializer maxItemsInObjectGraph="2147483646" />
 
 
      </behavior>
          </serviceBehaviors>
      </behaviors>
  </system.serviceModel>

Here is the same thing as an image with some hints:

The green line is the name of your service – this is the name of your subclass of the PersistenceMapperProvider.

The blue lines shows where we adjust some values to allow for bigger messages

The red lines just explains how reference and definition is separated

image

Having your own (enum) types

Another thing that got us stumped for a good 30 seconds was the unexpected server shutdown when trying to transfer types used by modlr-attributes over WCF when these types were not known to the service.

This is common place when you do your own Enumerations for example or any other handy attribute-type you might want to use.

You need to tell the WCF service about these types before the service is started. And you need to tell the client AND the server.

In a IIS hosted server use the Global.asax:

protected void Application_Start(object sender, EventArgs e)
{
    Eco.Wcf.Common.KnownTypesHelper.AdditionalTypes.Add(typeof(OrgeinheitTypEnum));
    Eco.Wcf.Common.KnownTypesHelper.AdditionalTypes.Add(typeof(ECObjectTypEnum));
}

And on the Client add it to Main:

static void Main()
{
    Eco.Wcf.Common.KnownTypesHelper.AdditionalTypes.Add(typeof(OrgeinheitTypEnum));
    Eco.Wcf.Common.KnownTypesHelper.AdditionalTypes.Add(typeof(ECObjectTypEnum));
    

When things do not work – complete darkness

Debugging the WCF issues was initially really annoying and complex – “Unexpected server shutdown” and nothing else…

But luckily it easy to turn on explicit logging in WCF. Go like this in the server web.config:

<configuration>
 
<system.diagnostics>
  <sources>
    <source name="System.ServiceModel"
            switchValue="Information, ActivityTracing"
            propagateActivity="true">
      <listeners>
        <add name="traceListener"
            type="System.Diagnostics.XmlWriterTraceListener"
            initializeData= "c:\temp\WCFTracelog.log" />
      </listeners>
    </source>
  </sources>
</system.diagnostics>
 
</configuration>

This will give you a file with a lot of information at c:\temp\WCFTracelog.log.

Like when I had removed one of the AdditionalTypes.Add statements from above the log look like this:

image

I hate ASP.NET

Yes it is true – I am not going to lie about it – I hate ASP.NET… But still it has its charms – the ability to just work on every client is actually worth something. But ASP.NET solutions are really just a million pieces of crap flying in close formation so that it resembles an application…

So me being this strongly-typed person that I am, how can I still deliver ASP.NET stuff without puking all over myself from disgust?

Well I guess it is not possible to completely NOT use the ASP.NET framework – but at least I want to use it as little as possible and certainly not for very straightforward stuff like showing up business objects in a standard UI with comboboxes, edit and grids.

If I can catch what I want in a model in like 5 minutes I do not want to spend more than 5 minutes to get it up and running. If I am satisfied I can spend more time on tuning it to “perfection” (hey its ASP.NET we talk about) but the basic stuff of fetching and editing and applying and persisting – 5 minutes tops. If I can get these things going in 5 minutes – fine – otherwise I want to ship it away to India for production. In India they hate ASP.NET as well – but they love the money.

Ok – Maybe MVC is the solution – NOT! MVC breaks my fingers from typing and I am still left with the disgusting html wiring of the UI – the very thing that makes me puke and it simply takes for ever.

So what am I saying here? What is my recommendation?

Go declarative – do things only once – use a framework from the future

Using Enterprise Core Objects – the model driven framework that actually works – a.k.a ECO I create this model:

image

Notice the “/” on Order.TotalCost and on OrderItem.CostForRow – these are derived attributes. Defined in Object constraint language (OCL – a rather boring but cool OMG standard) as such:

self.OrderItem->Collect(a|a.CostForRow)->sum()

(self.Quantity*self.Article.Cost)+(self.Quantity*self.Article.Weight*self.Order.DeliveryType.CostPerKiloGram)

Ok that took me like 5 minutes – better hurry up. I create a viewmodel:

image

Sure looks like a lot of typing but since the editor is Model driven I can more or less just pick and choose:

image

Ok… Maybe I have spent another 5 minutes on this…

That means I would have 10 minutes to get it up and running in ASP.NET.

Drag on a ViewModelASPNET control on a WebForm and set its viewModelName to the name of the viewmodel from above:

<cc1:ViewModelASPNET ID="ViewModelASPNET1" runat="server" 
   AutoApplyBeforeInternalDataBind="True" 
   DataSourceID="EcoDataSource1" EcoSpaceManagerID="EcoSpaceManager1" 
   GridsHasDeleteButton="True" GridsHasEditButton="True" 
   GridsHasSelectButton="True" GridSizeFixedWithScrollbar="True" 
    ReadOnly="False" 
   ViewModelName="ViewModelOrder" 
    PostbackOnComboboxChange="true"
     CommandoColumnWidth="32"
    />

Add some styling and background images and hit F5:

image

Ah, it still looks like shit but it is working – I can now spend days on getting it to look the way I want with css. The thing is that:

The ComboBoxes shows up the correct rows
Changing a ComboBox updates the single links in the correct object
The Totalcost is updated and displayed correctly
The buttons execute the domain logic as defined.
I can select, delete or edit Grid rows.
Data is persisted on the server.
The ViewModel has ReadOnly and VisibleExpressions that controls all the webcontrols

Declarative is nice! I still hate ASP.NET though…

Saturday, December 25, 2010

Allowing return key in some cells of DataGrid but not in others

As I use the EAInformation screens in AppComplete I found that it would be good to be able to accept multi line input in some grid cells.

As the EAInformation UI is completely built with ViewModels and Styles my first approach was to fix this in the Style. However I had, and still have, a hard time to figure out just how to get the style dynamic enough so that it could look at what it displays so that it can decide if it should accept return or not.

So if you have a different solution for this problem – enlighten me please…

Anyway this is what I have; classes with attributes that has the type “Text”:

image and imageetc...

These attributes will be treated as System.String in ECO maintained code:

[UmlElement(Id="84e4b74b-ee5e-4642-9bd3-9152959e9264", Index=Eco_LoopbackIndices.SLAText)]
[UmlTaggedValue("Eco.PMapper", "StringAsText")]
[UmlTaggedValue("Eco.Length", "-1")]
public string SLAText {
  get {
    return ((string)(this.eco_Content.get_MemberByIndex(Eco_LoopbackIndices.SLAText)));
  }
  set {
    this.eco_Content.set_MemberByIndex(Eco_LoopbackIndices.SLAText, ((object)(value)));
  }
}

But as you see above ECO adds a tagged value that defines the suggested Persistence mapper. I was thinking that I can use this tagged value to allow grid columns that show an attribute with this PMapper to accept return and capture multiline input.

Side note: How does ECO decide to treat Text as String, and How does ECO know to use the StringAsText persistence mapper?
In the install directory ECO finds the EcoDataTypes.XML (C:\Program Files (x86)\CapableObjects\ECO\6.0\config\EcoDataTypes.xml). And in this file ECO finds this listing:

<Type CanonicalName="Text" Type="System.String">
  <CommonName Name="text" CaseSensitive="false" /> 
  <CommonName Name="memo" CaseSensitive="false" /> 
  <LanguageName Language="C#" Name="string" /> 
  <LanguageName Language="Delphi" Name="string" /> 
  <LanguageName Language="Oxygene" Name="string" /> 
  <LanguageName Language="VB" Name="String" /> 
  <TaggedValue Tag="Eco.PMapper" Value="StringAsText" /> 
  <TaggedValue Tag="Eco.Length" Value="-1" /> 
 </Type>

You are free to add your own data types to this file, and also to use your own persistence mappers if you have defined your own.

So back to the main issue – how can I inject my own dynamic behavior in the ViewModel driven UI? This is what I did:

private void HookAllGridsToEnableReturnInTextColumns(ViewModel.WPF.ViewModelWPFUserControl UC)
{
    foreach (var x in UC.ViewModel.AllViewModelClasses.Values)
    {
        foreach (var y in x.Columns)
        {
            if (y.SpawnedArtifacts.ContainsKey("grid"))
            {
                (y.SpawnedArtifacts["grid"] as DataGrid).PreviewKeyDown += 
                          new KeyEventHandler(EAInformation_PreviewKeyDown);
            }
        }
    }
}

The code above takes a ViewModelWPFUserControl – finds the ViewModel-runtime that by the way is the same for all supported UI-styles (ASP.NET, Winforms, WPF and Silverlight). It looks for ViewModel columns displayed as Grid components – and when it finds one it hooks the PreviewKeyDown event to a local event handler.

Then the event handler is implemented this way:

void EAInformation_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Return)
    {
        DataGridCellInfo dgci = (sender as DataGrid).CurrentCell;
        ViewModelClass vmc = ((sender as DataGrid).Tag as ViewModelClass);
        foreach (var x in vmc.Columns)
        {
            if (x.SpawnedArtifacts.ContainsKey("control") && x.SpawnedArtifacts["control"] == dgci.Column)
            {
                if (x.ModelInfo != null)
                {
                    ITaggedValue tv = x.ModelInfo.TaggedValues.GetItemByTag(EcoTaggedValues.PMapperName.Tag);
                    if (tv != null && tv.Value == "StringAsText")
                    {
                        IInputElement c=Keyboard.FocusedElement;
                        if (c is TextBox)
                            (c as TextBox).AcceptsReturn = true;
                    }
                }
            }
        }
    }
}

The code above check if Return is pressed, if so, and if CurrentCell belongs to a column that was implemented by a ViewModelColumn that get its data from a model-class-attribute that use a persistence mapper of StringAsText – if all this is true and the focused element is a TextBox (this is the case when the cell is in edit mode) then we instruct the TextBox to accept return-key-strokes.

image

And that is it. With this article I wanted to show that the ViewModels are by no means a cul-de-sac. They are just a declarative way to get you further in the right direction with less code. You can and should use the meta information from your model to create generic code that does stuff that you want. Not only does this minimize the code you need to maintain – it also raise the quality since code written this way acts the same all over.

Sunday, December 5, 2010

Enterprise architect information

I wrote this other article some time ago. The principle remains but we have a lot of input from real life experience what one requires to successfully maintain all the axes of information needed in Enterprise Architecture.

We have applied this knowledge to create a tool that is now part of AppComplete – we call it EA-Information.

Processes

image

The first axis of information is the Processes – you can define the Steps of the process and the Stakeholder’s motivation for having this process in the first place.

Information

image

The second axis of EA-information is Information – here we can catch and see what the business call things – the catalog term – what states the catalog terms can have – according to the business. We can also define how this catalog term is implemented with classes or attributes. If we are 100% DDD compliant (as defined by Eric Evans book DDD – Domain Driven Design) the Catalog terms will have the exact same names as our classes. You will find that this is very good idea and it gives you the ubiquitous language between systems and business that everyone wants but very few manage to get and keep over time.

Having a separation between Catalog terms and Classes is an acceptable solution that enables both DDD implementations and also more traditional approaches.

When the language in the business and in the IT- systems are not ubiquitous this separation of axis enables us to define the lexicon between the two languages.

Actors

image

The Actors are the named Roles of the Business – they may have motivation to engage in processes and they may have user stories for specific steps of processes.

Applications

image

The fourth axis of information is Applications – we need to know the tools of the business. It is important to know the tools and in the end what information the tools contain in order answer questions about what will happen if an application is temporarily down or needs to be replaced.

The applications are one thing – but most applications are divided into modules or application parts. This is also defined in the screen above.

If you want to detail the use cases for these tools you can do so by defining ViewModels in AppComplete – the ViewModels will not only exactly explain what information that is used for that use case but also enables you to prototype or develop user interfaces to are suitable for the task at hand.

Infrastructure

image

The fifth axis of information in the AppComplete – EA-Information tool is Infrastructure.

Here we can define infrastructure nodes that our applications or part of our applications depend upon.

Having this information documented makes it easy to answer questions like “can we de-commission Server X or not”. And  questions like “I need to replace the router on floor 5, can I do it Thursday?” can be answered by tracking back what applications depend on it, then find what processes steps that use the applications and in the end find the Actors and Stakeholders involved.

Process steps

image

The process steps are really the core of the EA-information and as such you can explain in detail what the inputs and outputs are – you can also express if the step needs some information from another source than the input – we call this Resources.

This information is expressed with the Catalog Terms so you get full cross reference between all the axis in the EA-Information.

Information at your fingertips

The EA-Information shows up in the other views of AppComplete. You can show single steps in Process diagrams:

image

And Catalog Terms show up in the classes in Class Diagrams

image

And Cross references are available in the Auto-Diagrams

image

Summary

We are humble – we do not know everything – but we still think that we are on the right track. We are open for suggestions and we want partners. We can offer very competitive terms on AppComplete; AppComplete is a the application name that combines the tools EA-Information, Modlr, Prototyper, WECPOF, Reverse Database and Documenter.

image

Diagrams in Diagrams

In AppComplete you can create three types of diagrams

1. Class Diagrams

Class diagrams of AppComplete

 

2. State Diagrams

State diagrams of AppComplete

3. Process Diagrams

Process diagrams of AppComplete

What at least I think is very cool is that any diagram can hold any other diagram (new from December). So you can get all information in one diagram:

image

You cannot work in the placed diagrams – but if you double click them you will navigate to them.

Recurse Diagrams

If you are like me you probably ask yourself “can I recurse the diagrams”? Lets have a look what happens when I take the Class diagram from above that shows two placed diagrams (one state diagram and one process diagram) and add it to the Process diagram – that then should show up how many times?

Diagram of diagram

Cool – but the we hold of the recursion to 2 levels – I had to – or my mind would melt…

Lets switch back to the class diagram:

image

Cool – I like it. I Like WPF!

Reverse engineer a database - again

Green field development is a one thing – mastering projects that already have a lot of data is another. This is where the Reverse tools come into play.

I am doing work for an Insurance company – they are challenged by the soft wind of change that never seems to stop.  New products, new regulations, new technology, new clients, new business areas, new employees – in short everything is challenged by a relentless “let us move on” attitude.

Of course  this is common place for all business – competition will force you to evolve or die.

The IT-department needs to be Agile to avoid becoming the heavy-set-we-cannot-do-it-that-way part of the company that limits and slows evolution down.

I applied AppComplete on their database just to see what it could do.

image

The reversing mechanism runs thru the Schema of the database and creates Classes of the Tables, attributes of Fields and Associations of primary and foreign key pairs:

image

This is good news because I can now draw diagrams that can help me understand what the information is all about.

image

But still have the overview that AppComplete’s AutoDiagrams offer:

image

Since the information in the database now is explained in a the model I can create ViewModels that run and shows the real data with WECPOF explained here.

Real life experiences

Even if everything is just Dandy I can see, when comparing the database schema and Model, that some things are missing. I find some missing associations, missing classes and missing attributes.

Why is that? While the Reverse mechanism of AppComplete use the Schema of the database to draw conclusions about the model – the Schema might not be the complete truth.

After all developers can always join things in SQL even if those things does not have an explicit primary/foreign key definition.

Developers can use tables that has no primary key according to the Schema etc… In short the Reverse mechanism is hampered by crappy input.

Defining Persistence mapping manually

I suspect that the “Crappy input” fact is common place and AppComplete must be able to do adapt even in these situations.

Luckily it does; you can add missing classes manually, explaining what the PrimaryKey is in the properties:

image

You can also add Associations this way:

image

So that is the way it actually works – Fine. Hard work to look up missing details by browsing the database schema and comparing with the model.

It will not happen – too much work – is there another way?

Aided definition of Persistence Mapping

The latest versions of AppComplete has a way to browse the database Schema so you do not need to switch tools. Again right click the Package, choose Functions, Reverse Database:

image

Click Analyze db:

image

The schema shows up – if you click “Go!” the process will start to clear your existing package content and fill it up with the stuff found in the Schema – You do not want to do that if you are largely happy with your model – just missing some details.

Instead you can click the new tool “Reverse worker”:

image

This UI shows all the Tables in the DB. Select one Table and you see all the columns in that Table. You can use the buttons “Use as PK(primary key) or Attribute” and “Use as FK(foreign key)” to pick columns:

image

If you then move on to step 4 “Find possible actions in the Model” the tool suggest what you can do with the picked columns:

image

In this case we can add an Association.

Depending on if the Table is used by any of your Model classes or not you can also get the option to add the Class:

image

So this tool does the same thing that you can do manually explained earlier in this article – but it saves you the trouble of using some SQL-Browser, copy and paste SQL-Names and Clicking and editing Persistence mapping attributes of the model.

 
Contact Us | Terms of Use | Privacy Statement © 2009 CapableObjects