.NET Licensing - ode to monolithic applications?

The Microsoft .NET Framework has a built in licensing technology. It can be found in the namespace System.ComponentModel and System.ComponentModel.Design. Here is a small sample implementation of the minimal required classes: A lot of component producers use this licensing model – so does Tx Text Control – the component that I wanted to use. As a user you just create a *.licx-file, include it into the project as “embedded resource” and add the components that should be licensed by their fully qualified type names – one per line: During the build the LC-Task executes the license compiler (LC.exe). The license compiler is part of the .NET SDK that is part of the Windows SDK. If you have the Windows SDK 8.1 or Visual Studio 2013 installed it can be found at “C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\”. The result is the “Licensing.dll.licenses” file that is embedded by the C#-Compiler (Csc.exe) in the next step. During runtime the LicenseProvider-attribute is evaluated and the defined license provider is handed over to the System.ComponentModel.LicenseManager’s Validate method. This call forwards to the internal method ValidateInternalRecursive which then calls the GetLicense method of the LicenseProvider. The first argument of the GetLicenseCall is of type LicenseContext and at runtime filled with the static held instance of the internal class RuntimeLicenseContext. To resolve the license key the method GetSavedLicenseKey is called on the LicenseContext. The implemention offers two options to resolve the key: Resolve from URI: new Uri(new Uri(AppDomain.CurrentDomain.SetupInformation.ApplicationBase), AppDomain.CurrentDomain.SetupInformation.LicenseFile) Resolve from Embedded Resource: The lookup on references/loaded assemblies is only processed, if there is NO entry assembly - for instance within ASP.NET that is the case. But my intend was to create a build task for MsBuild that converts Microsoft Word’s DOCX files into PDF documents. So I have an entry assembly (MsBuild.exe). The entry assembly knows nothing about TX TextControl – and that is a good thing! I have no control over the entry assembly (MsBuild.exe). A situation I guess to find in every composite UI/modular desktop application. No wonder the monolith is often the preferred architecture especially on the desktop! After an intense debugging session through the framework sources (supported by red gate’s Reflector) I wrote a small helper class. WARNING: I use reflection to access internal types and private fields and modify their values – this means: If Microsoft decides to change their internal implementation it might not work anymore. But as we as can see the code was written for .NET 1.0 and has not been updated in the last 10 years: It’s not very likely that changes will happen. Now I just need to call LicenseLoader.LoadLicensesFromCallingAssembly() before the Tx Text Control component is instantiated the first time and everything works as expected. HTH

Are SCM check-out’s contemporary?

My VCS story began with Microsoft Visual Source Safe. I was happy... I had my files versioned. I could view differences in file versions. I could restore previous versions. I could view the history of a file. ... until the IDE started to crash, I had corrupted files and so on. http://www.flickr.com/photos/nesster/5823554695/ So I gave CVS and then SVN and TFS a try. I was happy... I could work with branches I could version source code “over HTTPS”. I could view file versions over HTTPS. ... until I saw a GIT introduction on the .NET Open Space presented by Alexander Groß. I was shocked about how I had worked before! He showed that it is not necessary to explicitly check-out and check-in files. I almost all areas of software development we try to align with business and to focus on the features that help or supports users or customers at their processes (E.g.: OOD, DDD, etc...). So why should I commit a change set just because I want to rename a file a second time? That is not a feature. It’s not even the result of a refactoring. Its just to satisfy the tool. Here are a few reasons why: Refactoring is an important part of the process to maintain a healthy and high quality code base. It means changing the structure... Naming I one of the hardest disciplines in software development. I don’t thing it helps anybody when there is an additional burden called the check-in. From my experience It holds people back from improving the code. 2010 I moved into the DVCS world. I started with HG and later moved on to GIT. I am happy... I can focus on the features. The SCM understands branching The SCM understands refactoring The SCM understands merging Last year on the NRW Conf my friend Ilker Cetinkaya held a lecture about commit messages. In his opinion the commit message should tell a story and answer the questions: What, why & how. He sowed really nice examples of commit messages almost equal to a blog post or a developer diary. Focusing on the Feature (LOB) and providing details about the technical realization. Markdown is an ideal format here. I cannot agree more. After the conference we discussed non-feature-commit-messages and agreed there should just be one: “Rechnerwechsel” the German term for “Switching the Machine”. When I join a project of a customer I sometimes still see SCM systems that still require explicit check-ins. My pleading Let developers focus on the features to deliver better results. Everybody has just 100% to give. Don’t take even a few percent of the developer productivity to hassle with a SCM just for the SCM. Version control exists to support people. Not to change the way people work: The motivation and empowerment of programmers has a direct and strong relationship to the quality of  the software.

Datenbank Autonomie

Oder warum sollten sich mehrere Anwendungen nicht dieselbe Datenbank teilen? http://www.flickr.com/photos/breville/10731809645/sizes/l/ Viele Köche verderben den Brei: Diseconomy of Scale Eine gemeinsame Datenbank (geteilt zwischen Anwendungen und/oder Teams) sorgt für unterschiedliche Interessen und erhöhten Absprachebedarf, damit es nicht zu einer Art Wildwuchs kommt. Wenn keine klaren Schnittstellen definiert sind sinkt die Produktivität aufgrund des erhöhten Kommunikationsaufwandes. Das gilt in Firmen unter Abteilungen und Mitarbeitern, genauso wie für Software-Projekt-Teams als auch für Software selbst. Bei wenigen Parteien ist die Komplexität oft noch nicht zu sehen. Desto mehr Parteien es werden, desto komplexer wird es jedoch. Wikipedia: http://en.wikipedia.org/wiki/Diseconomy_of_scale “Diseconomies of scale are the forces that cause larger firms and governments to produce goods and services at increased per-unit costs” Zu Deutsch: “desto mehr Parteien an einer Sache beteiligt sind, desto höher wird der Kommunikationsaufwand.“ Dazu gibt es auch eine mathematische Formel: Workers Communication Channels 1 0 2 1 3 3 4 6 5 10 n Zur Thematik in der Software-Entwicklung findet man folgende Definition: http://www.softwaremetrics.com/se.htm “In all software projects there are some basic principles which cause diseconomies of scale. That is: Communication becomes difficult as project becomes larger. Multiple logical paths grow in a nonlinear manner as size increases. Interrelationships of functions grow geometrically as project becomes large. Zu Deutsch: “In allen Software-Projekten gibt es einfache Gründe, die zur negativen Produktivität führen. Diese sind: Kommunikation wird schwieriger, wenn das Projekt größer wird. Wenn ein Projekt größer wird, wachsen die Interessen mit un-linearem Faktor auseinander. Abhängigkeiten von Funktionalitäten steigen im Quadrat wenn das Projekt größer wird. Dazu findet man beim „Massachusetts Institute of Technology“ (MIT) die folgende These um die Komplexität einzugrenzen: http://citeseerx.ist.psu.edu/viewdoc/download?doi= „… a manager could choose to divide the project into several smaller projects in order to increase the productivity.“ Zu Deutsch: “Ein Manager kann sich dazu entscheiden das Projekt in kleinere (unabhängige) Projekte zu teilen, um die Produktivität zu erhöhen.” IBM schreibt dazu in einem Whitepaper zu Software Economies wie die Ressourcen in einem Software-Projekt zu berechnen sindftp://public.dhe.ibm.com/common/ssi/ecm/en/raw14148usen/RAW14148USEN.PDF: Resources = (Complexity) * (Process) * (Teamwork) * (Tools) Wobei je 10% weniger beim Vorgänger mehr als 10% mehr Produktivität beim Nachfolger erzeugen. In diesem Dokument wird auch sehr gut Argumentiert, warum ein Wasserfall-Model (Erst alles Planen und dann erst Bauen, gegenüber einem agilen Ansatz(Kleine Iterationen von Planung und Ausführung zur besseren Kurskorrektur getrieben durch sich mit der Zeit ändernde Anforderungen) im Nachteil ist. Abstraktion und Muster/Patterns Die Abstraktion dient in der Software-Entwicklung zur Steigerung der Robustheit gegenüber Änderungen. Seit (spätestens) 21.10.1994, dem Erscheinungsdatum von „Design-Patterns“ der „Gang of four“ (http://en.wikipedia.org/wiki/Design_Patterns), sollte bekannt sein, dass Abstraktion und lose Koppelung höchste Güter er Software-Entwicklung sind. Als Beispiel dafür der Mediator (http://www.cs.ucsb.edu/~mikec/cs48/misc/Design_Class_Diagrams.htm): Eine Komponente, die zwischen den Anderen steht, um die Komplexität und das Wissen übereinander zu verringern. Schon in einer einzelnen Anwendung gehört es zu den „best practices“ den Datenzugriff zu abstrahieren(http://martinfowler.com/eaaCatalog/repository.html) um Änderungen an einer zentralen Stelle zu verwalten und nicht über die gesamte Anwendung ausufern zu lassen. Direct Data Access vs. Services Der direkte Zugriff auf eine Datenbank zieht bei einer Änderung des Schemas, also der Datenbank-Strukturen, z.B. hervorgerufen, durch Perfomance-Anforderungen, Geschäftsprozessänderungen oder der Migration auf eine neue oder andere Datenbankversion, Entwicklungsaufwände in JEDER direkt darauf zugreifenden Anwendung nach sich. Dies kann durch Abstraktion des Datenzugriffs undAutonomie der der Datenbank verhindert werden. Wikipedia schreibt dazu (http://en.wikipedia.org/wiki/Database_abstraction_layer): „Database abstraction layers reduce the amount of work by providing a consistent API to the developer and hide the database specifics behind this interface as much as possible“ Zu Deutsch: “… Abstraktion reduziert die Aufwände durch einen klar definierte Schnittstelle für den Entwickler und versteckt/schützt die Implementierungsdetails so gut wie möglich” In einem der bekanntesten Portalen der Software-Entwicklung, in dem alle Programmiersprachen diskutiert, und die Antworten allen bewertet werden können findet man den folgenden Eintrag:http://stackoverflow.com/questions/1530551/direct-acces-database-vs-web-service “Direct database access couples you tightly to the schema. Any changes on either end affects the other.” Zu Deutsch: “Jede Änderung auf einer Seite hat Auswirkungen auf alle anderen” Und… „ I would try to go the direct database access route, unless several applications need to share the data...“ Zu Deutsch: “Ich würde den direkten Datenbankzugriff wählen, es sei denn, mehrere Anwendungen sollen sich die Daten teilen…“ Zu „Entwicklungen“, die über die Zeit eine Datenbank mach und die Vorteile eines zentralisierten Datenzugriffs (http://www.agiledata.org/essays/implementationStrategies.html): “…a single encapsulation layer … reduce the effort it takes to evolve your database schemas” Zu Deutsch: “… ein Einzige Datenzugriffsschicht reduziert die Aufwände die entstehen, wenn eine Datenbank sich weiterentwickelt/wächst” Globaler Datenzugriff: Die neuen globalen Variablen Der Einsatz von globalen Variablen ist seit Jahren in der Software-Entwicklung verpönt (http://c2.com/cgi/wiki?GlobalVariablesAreBad). Das liegt daran, dass Code, der mit globalen Variablen arbeitet folgende Eigenschaften mit sich bringt: Er verlässt sich darauf, dass eine Variable einen bestimmten Wert enthält. Er lässt sich also nur durch aufsetzen diese Vorbedingungen (Infrastruktur) testen. ABER: Jeder kann den Wert ändern, da ja keiner die Zuständigkeit besitzt (z.B. eine Funktionalität/Service) zu kontrollieren, ob dies zum aktuellen Zeitpunkt auch korrekt ist. Dadurch: Entsteht ein System von Unvorhersehbarkeiten Eine Datenbank mit „Zugriff für ALLE“ verhält sich genauso. Wie eine globale Variable oder eine Gruppe Kinder zu einem Süßigkeiten-Glas. Das gilt übrigens technologieübergreifend - auch in JAVA und in allen anderen Programmiersprachen (http://stackoverflow.com/questions/2867862/service-bus-vs-direct-database-access). Es handelt sich dabei um ein Architektur- bzw. Vorgehens-Problem. Daten als Dienstleistung Wenn man sich fragt, was eine Anwendung will, würde man wohl eher sagen, dass sie mit den Daten arbeiten will (z.B. einen Geschäftsprozess abbilden), als, dass sie auf die Datenbank zugreifen will. Das würde sonst schließlich bedeuten, dass die Software zu Selbstzweck oder der Technologie willens existiert. Es ist wie beim Verschicken eines Briefes. Man muss nicht wissen, ob der Briefträger mit dem Fahrrad kommt, zu Fuß unterwegs ist oder mit dem Postauto ausliefert. Es zählt die Dienstleistung! Darüber schreibt Wikipedia: http://en.wikipedia.org/wiki/Data_as_a_service “As the number of bundled software/data packages proliferated and required interaction among one another, another layer of interface was required.” Zu Deutsch: “Wenn die Zahl der der Anwendungen/Daten wächst ist eine weitere (Abstraktions-) Schicht nötig” Service-orientierung Der Dienstleistungsgedanke ist nicht neu – vor allem nicht in der Software-Entwicklung (siehe Wikipedia http://de.wikipedia.org/wiki/Serviceorientierte_Architektur). Dabei geht uns nicht um „das große Enterprise“, sondern darum, die IT aus der Perspektive der Geschäftsprozesse und Anforderungen zu sehen. Dabei gilt (für uns) Think big, start small - Nach vorne sehen und sich keine Steine in den Weg von morgen zu legen UND die Aufwände zu jedem Zeitpunkt durch Kontrolle und Steuerung der Komplexität realistisch zu halten und somit agil reagieren zu können. Mit diesen Gedanken kommt auch ein anderer Blick auf Daten (http://citeseerx.ist.psu.edu/viewdoc/download?doi= Datenzugriff muss koordiniert und kontrolliert werden (Security und Änderungsresistenz) Daten gehören einem Dienst (so wird Kontrolle sichergestellt) Direkter Datenzugriff ermöglicht üblicherweise ein CRUD (Create, Read, Update & Delete – Erstellen, Lesen, Aktualisieren und Löschen) wohingegen ein Dienst die Funktionalität bereitstellt (z.B. „Bestellen“ oder „UmfrageAuswerten“). Änderungen am Schema und Skalierung Neben der Tatsache, das sich Geschäftsfelder erweitern und/oder ändern können und sich dadurch Änderungen an den Strukturen in der Datenbank ergeben können, bedeutet es (gerade) für eine (Web-)Plattform, dass wenn sie Erfolg, die Lasten steigen und andere Konzepte nötig werden um die Daten zu speichern und zu lesen. Ein zentralisierter Datenzugriff reduziert die Aufwände in den Anwendungen und ermöglicht Skalierung, Sharding(http://en.wikipedia.org/wiki/Shard_(database_architecture)) und Integrations-Konzepte (http://en.wikipedia.org/wiki/Data_Integration).

Fixing Msbuild Error msb3247 - Found conflicts between different versions of the same dependent assembly.

Set MsBuild Verbosity to find out which assemblies conflict: http://msdn.microsoft.com/en-us/library/ms164311.aspx msbuild.exe .\Compile.msbuild /verbosity:detailed ... There was a conflict between "xxx, Version=, Culture=neutral, PublicKeyToken=xxx" and "xxx, Version=1.0.12152.1, Culture=neutral, PublicKeyToken=xxx". "xxx, Version=, Culture=neutral, PublicKeyToken=xxx" was chosen because it was primary and "xxx, Version=1.0.12152.1, Culture=neutral, PublicKeyToken=0313e76cb5077f22" was not. References which depend on "xxx, Version=, Culture=neutral, PublicKeyToken=xxx" [D:\Projects\abc\bin\xxx.dll]. D:\Projects\abc\bin\xxx.dll Project file item includes which caused reference "D:\Projects\abc\src\Web.BuildServer\bin\xxx.dll". xxx References which depend on "xxx, Version=1.0.12152.1, Culture=neutral, PublicKeyToken=xxx" []. D:\Projects\abc\src\packages\yyy\lib\Net40\yyy.dll Project file item includes which caused reference "D:\Projects\abc\src\packages\yyy\lib\Net40\yyy.dll". yyy ... What means yyy references a version of yyy other than the one references by the project or another assembly. Check the Config files For Web-Applications the Web.config for all other project types the App.config file (even for class libraries). Make sure you don’t have a <runtime> section pointing to the wrong assembly version. Fix the error by binding the correct version. <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31BF3856AD364E35" culture="neutral"/> <bindingRedirect oldVersion="" newVersion=""/> </dependentAssembly> </assemblyBinding> </runtime> </configuration> Helpful utilities https://github.com/mikehadlow/AsmSpy

Python&rsquo;s urandom as non-admin

A few weeks ago I set up a new mercurial server fronted by “hgweb-cgi”. The application pool is, as python 2.66, in x64 mode. It has a dedicated ad account from the Managed Service Accounts OU. I set the privileges to deny logon locally and run as service and batch. Everything works fine… until you want to push: HTTP 502 Bad Gateway. IIS failed request tracing lead me to the relevant python source line: So I opened up the file in notepad and looked at the line… The “_urandom” is the one that’s breaking the thing. So I took a look at the os.py from the lib directory. Funky nice UNIX path. So I tried to create the directory “C:\dev\” set permission to everybody “full access” and added a dummy file called “urandom” - Still no success. I ended up with editing the Random.py: I’m amazed shocked that I need to edit the base library file.

NRW Conf 09

Auch in diesem Jahr veranstaltet der Just Community e.V. wieder das größte Developer und IT-Pro Community Event. Unter dem Motto „Check-In zum Wissensvorsprung“ holen wir am 28.08.2009 zahlreiche nationale und internationale Speaker nach Wuppertal. Neben den Vorträgen haben Sie natürlich auch dieses Jahr wieder viel Zeit für das Networking mit anderen ITlern aus Nah und Fern. Alle Informationen, wie die Agenda und eine Übersicht über die Speaker gibt es unter http://www.nrwconf.de/. Wir freuen uns, Ihnen auch dieses Jahr sowohl bekannte Gesichter, als auch neue Speaker vorstellen zu dürfen. Die Veranstaltung wurde in diesem Jahr möglich durch unsere Sponsoren: Hewlett Packard, devcoach, Microsoft Deutschland, Brockhaus AG, Itemis AG, sepago GmbH, MT AG, sowie weiteren Unternehmen. Eine weitere Neuerung in diesem Jahr ist der Workshop Day, der am Vortag der eigentlichen Konferenz – sprich am 27.08.2009 – in den Räumlichkeiten unseres Sponsoren Ontaris GmbH stattfindet. Der Developer-Workshop befasst sich mit der Microsoft Web Platform und behandelt die Themen Rich Internet Applications mit Silverlight 3.0 und Web 2.0 Applikationen mit ASP.NET AJAX und JQuery. Die Workshops haben eine begrenzte Teilnehmerzahl (je acht) um den Lernerfolg zu garantieren. Also schnell einchecken…

Executing CREATE statements from within Visual Studio 2005

If you try to run a CREATE statement in a query (right click on a database in the Server Explorer) you receive this message. So i wrote a small utility which will do the job for me. using System; using System.IO; using System.Data.SqlClient; using System.Collections.Generic; using System.Text; using System.Windows.Forms;   namespace MdfExec {     class Program     {         static void Main(string[] args)         {             string _cnStr;               if (args.Length == 2)             {                 _cnStr =                     "data source=.\\SQLEXPRESS;Integrated Security=SSPI;" +                     "AttachDBFilename=" + args[1] + ";User Instance=true;";             }             else             {                 OpenFileDialog fd = new OpenFileDialog();                   fd.AddExtension = true;                 fd.DefaultExt = ".mdf";                 fd.ShowDialog();                   _cnStr =                     "data source=.\\SQLEXPRESS;Integrated Security=SSPI;" +                     "AttachDBFilename=" + fd.FileName + ";User Instance=true;";             }               using (SqlConnection _cn = new SqlConnection(_cnStr))             {             using(SqlCommand _cmd = _cn.CreateCommand())                    {                     using (StreamReader fs = File.OpenText(args[0]))                     {                         _cmd.CommandText = fs.ReadToEnd();                         _cmd.Connection.Open();                         _cmd.ExecuteNonQuery();                     }                    }             }         }     } }   You can now right click on a *.sql file choose "open with ..." and select MdfExec.exe to execute the SQL statement. Since there is no second parameter (but needed to define to which database to connect) a OpenFileDialog will prompt:   Happy coding

.NET SummerCamp 2005 Leipzig

Torsten Weber invited me to do one day of sessions at the .NET Summercamp: I introduced .NET 2.0 and C# 2.0 and talked about Visual Studio 2005 Team System. It was the first time in Leipzig and i really liked it. Hopefully i'll be there next year too.