The GitHub way of blog discussion and commenting
Using the underlying power of GitHub, blog authors often take a step further and roll their own discussion and commeting systems.
The best examples are:
- Add a comment by sending a pull request by Mark Seemann
- Add a comment through the GitHub API by Ivan Zuzak
- Add a comment as a GitHub issue by Zach Holman
With the evolution of blog-aware static site generators, like Jekyll, GitHub is becoming a central part for hosting both blog content and comments.
Hackers, Developers, Programmers
The definitions about Hackers, Developers, and Programmers, that I like best are:
“Hackers are generally loners who don’t care if others can figure out their code (at least while they are in the mode or role of hacking). Thus, they build their own little world in it that fits themselves nicely so that they can hack fast, but the rest of the world be damned.” — c2.com/wiki
“On the ‘programmer’ vs. ‘developer’ debate: ‘Programmer’ focuses on the ‘craft’. ‘Developer’ focuses on the business. Both are valuable.” — @ploeh on twitter
I am a programmer — You?
xUnit.net Attributes Execution Order
The test below uses the xUnit.net framework and executes twice, since it is decorated with two data sources. The first data source is the built-in [InlineData] and the second data source is the custom [StringData].
[Theory]
[InlineData("foo", "bar")]
[StringData]
[Intercept]
public void Test(string a, string b)
{
}
xUnit.net invokes in exact order:
Initialization
[InlineData]consturctor[StringData]consturctor[InlineData]IEnumerable<object[]> GetData(MethodInfo, Type[])[StringData]IEnumerable<object[]> GetData(MethodInfo, Type[])
1st Run
[Intercept]consturctor[Intercept]void Before(MethodInfo)[Theory]supplying values for a and b taken from either[InlineData]or[StringData][Intercept]void After(MethodInfo)
2nd Run
[Intercept]consturctor[Intercept]void Before(MethodInfo)[Theory]supplying values for a and b taken from either[InlineData]or[StringData][Intercept]void After(MethodInfo)
Remarks
[Intercept] is defined as:
internal class InterceptAttribute : BeforeAfterTestAttribute
{
public override void Before(MethodInfo methodUnderTest)
{
}
public override void After(MethodInfo methodUnderTest)
{
}
}
It allows code to be run before and after each test is run.
[StringData] is defined as:
internal class StringDataAttribute : DataAttribute
{
public override IEnumerable<object[]> GetData(
MethodInfo methodUnderTest,
Type[] parameterTypes)
{
yield return new object[] { "cow", "zoo" };
}
}
XCOPY deployment for Code Contracts
If you don’t wish to install Code Contracts through the Windows Installer:
- Go to
\Program Files (x86)\MSBuild\4.0\Microsoft.Common.Targets\ImportAfterfolder. - Create a new file with name
CodeContractsAfter.targetsand paste the following XML:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CodeContractsInstallDir Condition="'$(CodeContractsInstallDir)'==''">CONTRACTS_PATH</CodeContractsInstallDir>
</PropertyGroup>
<Import Condition="'$(CodeContractsImported)' != 'true' AND '$(DontImportCodeContracts)' != 'true'"
Project="$(CodeContractsInstallDir)MsBuild\v4.0\Microsoft.CodeContracts.targets" />
</Project>
- Extract the contents from the Code Contracts Windows Installer using the lessmsi tool.
- Locate the
Contractsfolder in the extracted contents. - Replace the
CONTRACTS_PATHinCodeContractsAfter.targetswith the actualContractsfolder location.
Legacy Code Risk
Taking the risk to adjust the architecture of a legacy system and extend it in a nice and clean way.
Creating a context:
- Complex domain (e.g. life insurance)
- Many technologies are used, tightly coupled (e.g. Redis, db40, iBATIS, Quartz, Sparks, etc).
- The model has been designed around the Active Record (anti)pattern.
- In a few places there are also DAOs and/or Repositories.
- The Service Locator (anti)pattern has been applied everywhere.
- Almost everywhere, the SRP has been violated.
- Communication with any external Web Service is not guarded with a Circuit Breaker.
- And yes.. there are no tests..
(All the above yield sad customers, bugs, and slow performance.)
Against messy, tightly coupled, legacy code.
- Strive toward real SOLID principles
- Instead of doing Test-After Development Sins write test code trying to drive the SUT API and safely refactoring afterwards. The non-relevant Test Fixture setup is automated with AutoFixture decleratively with the xUnit.net extension.
- Instead of using the Service Locator use Dependency Injection patterns, such is Constructor Injection.
- Instead of using Active Record, Repositories and DAOs consider using Queries and Commands (as described in the first half of this post). This might result in more classes but each class is going to have one responsibility instead of two or more.
Why it is a risk?
The above require a few changes in the system architecture (e.g. in order to be possible to not use Service Locators, in order to be possible to use Services to query from the database instead of the Active Record way, etc.).
While the required changes are going to (initially) slow down the development process at the end the overall development is going to be faster.
Would you take the risk?
Database Schema Synchronization with SqlPackage.exe
SqlPackage is the descendant of VsDbCmd command-line tool. It creates, deploys, and packages SQL Server databases snapshots into a portable artifact called a DAC package, also known as a DACPAC.
Manual Database Schema Synchronization
- Create a New
SQL Server Database Project - On the newly created SQL Server Database Project:
- Right Click, Import, Database…
- Right Click, Properties
- In the Project Settings tab select target platform (e.g. SQL Server 2008)
- In the SQLCMD Variables tab enter in the
Localcolumn the path of SQL Server installation folder. Notice that the Local path overrides theDefaultpath.
- Go to
SQL > Schema Compare > New Schema Comparison- Select as source the newly created SQL Server Database Project.
- Select as target the database containing the schema to be synchronized.
Automatic Database Schema Synchronization
When there is no network access in production environment, the synchronization process can be automated.
Thanks to Dimitris Charalampidis who provided the steps below, the database schema synchronization can be automated as follows:
- Copy the created ‘.dacpac’ file from SQL Server Database Project build output path to the same folder as SqlPackage.
- Open a command console and execute the following command:
sqlpackage.exe /a:Script /sf:$Yourdatabaseproject.dacpac$ /tcs:"Data Source=$ServerName$;Database=$DatabaseName$;User id=$userid$;password=$password$;Trusted_Connection=false;" /op:DBSchemaCompareScript.sql /p:ScriptDeployStateChecks=True /p:BackupDatabaseBeforeChanges=True /p:IgnoreExtendedProperties=True /p:IgnorePermissions=True /p:IgnoreRoleMembership=True /v:Path1="$Path1$" /v:Path2="$Path2$"
- Replace:
- $Yourdatabaseproject.dacpac$ with the database project snapshot name you copied in the folder earlier.
- $ServerName$ with the target SQL Server instance name.
- $DatabaseName$ with the target database name.
- $userid$ and $password$ with the SQL Server Authentication credentials.
- $Path1$ and $Path2$ with the path to the SQL Server installation folder.
At this point you may want to add also the
/p:GenerateSmartDefaults=Trueswitch to provide a default value when updating a table that contains data with for columns that do not allow null values.
After a few seconds a file named DBSchemaCompareScript.sql will be created (you can change the name with the /op: switch value).
- Open the script file with Microsoft SQL Server Management Studio.
- Select
Query > SQLCMD Modeand execute the query.
After the query executes without errors, the database schema will be synchronized with the latest changes.
Remarks
The following files are required by the SqlPackage if the Microsoft SQL Server Data Tools is not installed in production environment:
- SqlPackage.exe
- Microsoft.Data.Tools.Schema.Sql.dll
- Microsoft.Data.Tools.Utilities.dll
- Microsoft.SqlServer.Dac.dll
- Microsoft.SqlServer.TransactSql.ScriptDom.dll