Wednesday 30 September 2009

Thursday 24 September 2009

Using idref when configuring objects

Using the idref element is "an error-proof way" to pass the id of one object to another in Spring.Net configuration files. Using idref is preferable because the IoC will validate that referenced objects exist at deployment time rather than waiting for objects to actually be instantiated.

So, this...

<object id="theTargetObject" type="..."> 
. . . 
</object> 

<object id="theClientObject" type="..."> 
  <property name="targetName"> 
    <idref object="theTargetObject"/> 
  </property> 
</object>

is prefereable to this...

<object id="theTargetObject" type="...">
. . .
</object>
 
<object id="theClientObject" type="...">
  <property name="targetName" value="theTargetObject"/>
</object>

See the Spring.Net documentation (section 5.3.2.1.1).

Constructor vs setter injection

Choosing between constructor or setter injection is not straight forwards and in practice can lead to difficult choices. In cases where objects have a large number of required dependencies this issue really raises its head.

Spring.Net's documentatioon states:
"The Spring team generally advocates the usage of setter injection, since a large number of constructor arguments can get unwieldy, especially when some properties are optional. The presence of setter properties also makes objects of that class amenable to reconfigured or reinjection later. Managment through WMI is a compelling use case.

Some purists favor constructor-based injection. Supplying all object dependencies means that the object is always returned to client (calling) code in a totally initialized state. The disadvantage is that the object becomes less amenable to reconfiguration and re-injection...

...Since you can mix both, Constructor- and Setter-based DI, it is a good rule of thumb to use constructor arguments for mandatory dependencies and setters for optional dependencies."
Martin Fowler also has a few words of advice on this issue:
"The choice between setter and constructor injection is interesting as it mirrors a more general issue with object-oriented programming - should you fill fields in a constructor or with setters.

My long running default with objects is as much as possible, to create valid objects at construction time.... Constructors with parameters give you a clear statement of what it means to create a valid object in an obvious place. If there's more than one way to do it, create multiple constructors that show the different combinations...

...But with any situation there are exceptions. If you have a lot of constructor parameters things can look messy, particularly in languages without keyword parameters. It's true that a long constructor is often a sign of an over-busy object that should be split, but there are cases when that's what you need...

...If you have multiple constructors and inheritance, then things can get particularly awkward. In order to initialize everything you have to provide constructors to forward to each superclass constructor, while also adding you own arguments. This can lead to an even bigger explosion of constructors.

Despite the disadvantages my preference is to start with constructor injection, but be ready to switch to setter injection as soon as the problems I've outlined above start to become a problem." - http://martinfowler.com/articles/injection.html#ConstructorVersusSetterInjection
The Spring.Net documentation goes on to point out that with constructor injection it is possible to get into a situation where you have unresolvable circular dependencies. These situations are detected by Spring.Net which throws an ObjectCurrentlyInCreationException. Spring offer some helpfull advice:
"One possible solution to this issue is to edit the source code of some of your classes to be configured via setters instead of via constructors. Alternatively, avoid constructor injection and stick to setter injection only. In other words, although it is not recommended, you can configure circular dependencies with setter injection."
In short the choice between setter and constructor is not clear and you need to make your own choice based on circumstances. This ambiguity is arguably a weakness with Dependency Injection.

Configuration of generic types in Spring.Net

Whe using Spring.Net's XML configuration files defining generic types requires a non-intuitive trick or two.

1. The left bracket () must be written using XML escape syntax (i.e. &lt;).
2. Generic type arguments can not be fully assembly qualified as the comma is used to separate generic type arguments.

A generic object definition might look like this:

<object id="myFilteredIntList" type="GenericsPlay.FilterableList&lt;int>, GenericsPlay">
    <property name="Name" value="My Integer List"/>
</object>

Note the use of &lt;.

In the case of item 2 above it is suggested you use type aliases to clarify the text:

<typeAliases>
    <alias name="GenericDictionary" type=" System.Collections.Generic.Dictionary&lt;,>" />
</typeAliases>
<object id="myGenericObject"
type="GenericsPlay.ExampleGenericObject&lt;GenericDictionary&lt;int , string>>, GenericsPlay" />

instead of:

<object id="myGenericObject"
type="GenericsPlay.ExampleGenericObject&lt;System.Collections.Generic.Dictionary&lt;int , string>>, GenericsPlay" />

Yuk.

See section 5.2.6.1 of the Spring.Net documentation for details.

Wednesday 23 September 2009

Enabling or disabling full-text indexing

To identify full-text indexes on a server run:

SELECT 
  object_id, 
  OBJECT_NAME(OBJECT_ID) AS ObjectName, 
  is_enabled, 
  has_crawl_completed, 
  crawl_type, 
  crawl_type_desc, 
  * 
FROM sys.fulltext_indexes 

To enable an index run:

ALTER FULLTEXT INDEX ON [ObjectNameHere] ENABLE

To disable an index run:

ALTER FULLTEXT INDEX ON [ObjectNameHere] DISABLE

Note that [ObjectNameHere] should be replaced with the object name identified from the results of the first query.

Querying SQL Profiler data

If you use the SQL Server Query Profiler and log results to a table you can get some basic stats from the results with these queries:
-- Find most frequently used queries 
SELECT DISTINCT 
    cast(textdata as varchar(150)) as textdata, 
    avg(duration) as avg_duration, 
    count(duration) as Occurences 
FROM 
    [ProfilerTableNameHere] 
GROUP BY 
    Cast(textdata as VarChar(150)) 
ORDER BY 
    count(duration)desc 

-- Find most inefficient queries 
SELECT DISTINCT 
    cast(textdata as varchar(150)) as textdata, 
    avg(duration) as avg_duration, 
    count(duration) as Occurences 
FROM 
    [ProfilerTableNameHere] 
GROUP BY 
    Cast(textdata as VarChar(150)) 
ORDER BY 
    Avg(duration)desc

Identifying tables in a database

If you need to identify the tables in a database including their row counts, column counts and data size try the following SQL:

USE [DatabaseNameHere] 

CREATE TABLE #temp ( 
  table_name sysname , 
  row_count INT, 
  reserved_size VARCHAR(50), 
  data_size VARCHAR(50), 
  index_size VARCHAR(50), 
  unused_size VARCHAR(50)) 

SET NOCOUNT ON 

INSERT #temp 
EXEC sp_msforeachtable 'sp_spaceused "?"' 

SELECT 
  a.table_name, 
  a.row_count, 
  COUNT(*) AS col_count, 
  a.data_size 
FROM 
  #temp a 
INNER JOIN 
  information_schema.columns b 
ON a.table_name collate database_default 
= b.table_name collate database_default 
GROUP BY 
  a.table_name, 
  a.row_count, 
  a.data_size 
ORDER BY 
  CAST(REPLACE(a.data_size, ' KB', '') AS integer) DESC 

DROP TABLE #temp

Monday 21 September 2009

Problems rendering partial views

Don’t forget that when calling Html.RenderPartial() use a <% %> block and not a <%= %> block. Html.RenderPartial() doesn’t return a string of HTML but outputs directly to the calling view.

Don’t forget that because you are using a <% %>block the code elements must be ended with a semi-colon:

<% Html.RenderPartial("PartialViewName"); %>

Controlling data binding with ASP.Net MVC

If you use the UpdateModel() Controller helper method to bind data you can enforce which properties are bound to prevent unwanted data manipulation. There are three methods you can employ to provide MVC with an inclusion list of the properties to be bound.

Pass in an array of strings containing the names of the properties to be bound.

string[] properties = new[]{"Property1", "Property2"}; 
UpdateModel(myModel, properties);

Add a bind attribute to the controller action.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyAction( [Bind(Include="Property1, Property2")] MyModelType model ) { //... }

Add a bind attribute to your model type. Note that this can be either an inclusion or exclusion list.

[Bind(Include="Property1, Property2")] 
public partial class MyModelType { //... }

Thursday 17 September 2009

Defining closed vs open generic types

Generic types can be open or closed. A closed generic type is defined as follows:
"A constructed generic type that has no unspecified generic type parameters, either of its own of or any enclosing types or methods. Closed generic types can be instantiated. See also: constructed generic type, generics, generic type, generic type parameter, open generic type."
Conversely an open generic type is defined as follows:
"A constructed generic type in which one or more of the generic type arguments substituted for its generic type parameters is a type parameter of an enclosing generic type or method. Open generic types cannot be instantiated. See also: closed generic type, constructed generic type, generics, generic type argument, generic type parameter."
So, IList<Person> is a closed generic type, IList<T> is an open generic type.
Thursday 17 September 2009,

Wednesday 16 September 2009

Find a stored procedure containing specific text

To find a Stored Procedure containing specific text run the following SQL:

SELECT OBJECT_NAME(object_id) 
FROM sys.sql_modules 
WHERE
definition LIKE '%[text to search for here]%' AND
OBJECTPROPERTY(object_id, 'IsProcedure') = 1 
ORDER BY 1

Identify constraints for a table column

To find the constraints for  a given database column (without using the built-in SQL Managament Studio features) run the following SQL:

SELECT OBJECT_NAME(constid) 
FROM sysconstraints 
WHERE id = OBJECT_ID('table name here')
AND colid = 
    (
        SELECT colid 
        FROM syscolumns 
        WHERE id = OBJECT_ID('table name here') 
        AND name = 'column name here'
    )

Rebuilding XML indexes

To find the XML indexes in a database:

SELECT * FROM [sys].xml_indexes

To identify the primary XML index:

SELECT [sxi].name "Primary index name", [so].name "Table name" 
FROM [sys].xml_indexes sxi 
JOIN [sys].objects so ON (so.object_id = sxi.object_id) 
WHERE using_xml_index_id IS NULL

To identify the secondary XML indexes:

SELECT sxi.name "Secondary index name", so.name "Table name" 
FROM [sys].xml_indexes sxi 
JOIN [sys].objects so ON (so.object_id = sxi.object_id) 
WHERE using_xml_index_id IS NOT NULL; 

To rebuild an XML index:

ALTER INDEX [XML index name here] ON [table name here] REBUILD

Reassociating user logins

When restoring databases from backups on a developer machine you will probably need to create Logins for the application you are working on. The Logins will correspond to the Users used by the application but because the original Logins were created on a different server the Logins created on your development machine won't be correctly associated with the Users in the database.

To reassociate a Login with a database User run the following SQL:

EXEC sp_change_users_login 'Update_One', '[user name here]', '[login name here]'

More information and options here: http://msdn.microsoft.com/en-us/library/ms174378.aspx

Tuesday 15 September 2009

Controller can't be found gotcha

IIS needs to be set-up to use the Microsoft MVC framework or you will get an error along the lines of 'controller can't be found'. A new file extension needs to be added to IIS.
  1. Open the IIS MMC snap-in.
  2. View the properties for the webs site in question.
  3. Go to the Home Directory tab.
  4. Click Configuration...
  5. Add a new extension (.mvc).
    1. Map the extension to the aspnet_isapi.dll.
    2. Limit to the following verbs: GET,POST,HEAD,DEBUG.
    3. Uncheck the 'Check that file exists' and 'Script engine' checkboxes.

Thrive for Developers

Microsoft have launched a site dedicated to development in a downturn - http://www.microsoft.com/click/thrivedev/.

To quote Microsoft:

"We’ve heard from lots of developers that times are tough. You’re doing more with less, applying your skills more broadly, and maybe even learning new tools. That’s why we created Thrive – a one-stop community hub that offers job postings, technical content, and community resources."

Saturday 12 September 2009

Configuration error in Web.Config

If you get this error...


... check that the ASP.NET settings on the IIS Virtual Directory are set to the right ASP.NET version (i.e. version 2).

Play with LINQ using LINQPad

There is a free tool to help learn LINQ - LINQPad. This handy little application allows you to dynamically run LINQ queries against a data source and see the results instantaneously. You can even run plain SQL against the same data for comparison.

Download from http://www.linqpad.net/.

Thursday 10 September 2009

Setting ARITHABORT can affect query performance

MSDN documentation defines SET ARITHABORT as follows:
"Terminates a query when an overflow or divide-by-zero error occurs during query execution.
...
If SET ARITHABORT is ON, these error conditions cause the query or batch to terminate. If the errors occur in a transaction, the transaction is rolled back. If SET ARITHABORT is OFF and one of these errors occurs, a warning message is displayed, and NULL is assigned to the result of the arithmetic operation."
Note that this setting can have significant effect on query performance. It is quite possible for a query to run very quickly in SQL Management Studio but very slowly when run from code (e.g. ADO.Net). A possible explanation is that ADO.Net runs with ARITHABORT set to OFF whereas SQL Management Studio runs with it ON.

If a query is running very slowly from code it is worth checking if ARITHABORT should be set to on.

UpdateModel() and TryUpdateModel()

Model objects can be easily updated with form values using either the UpdateModel() or TryUpdateModel() methods on the Controller class. These methods are overloaded and there are a lot of variations but at its simplest the methods need only take a TModel.
[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(int id, FormCollection formValues) 
{ 
    Dinner dinner = _dinnerRepository.GetDinner(id); 
    UpdateModel(dinner); 
    _dinnerRepository.Save(); 

    return RedirectToAction("Details", new { id = dinner.DinnerId }); 
}

TryUpdateModel returns a boolean value if the update was successful. UpdateModel throws an InvalidOperationException should there be an problem with updating the model. UpdateModel and TryUpdateModel report any errors to the ViewData's ModelState; you don't have to add them via ModelState.AddError yourself.

The overloadde methods allow you to specify specific keys which are used to map object properties to form values. You can also optionally specify an object prefix for cases where form element names are in the form Prefix.ElementName (e.g. Dinner.Title).

Wednesday 9 September 2009

Why use the MVC AcceptVerbs attribute?

The [AcceptVerbs] attribute can be applied to action methods in a controller so that the appropriate overloaded method is invoked for a given request. ASP.NET MVC will automatically dispatch a request to the appropriate action method based on the HTTP verb.

The advantage of differentiating methods based on HTTP verb is that the same URL can be used for multiple opuposes (e.g. display and edit). This could be done with 2 separate URLs but the downside here is that it makes bookmarking pages difficult. For example, if an error occurs during a POST and we direct the user to a different page (one that displays the eror message) and the user bookmarks tghis page they have a bookmark to an 'invalid' page.

By using the [AcceptVerbs] attribute we can have a single URL that is sagfe to bookmark even after a POST.

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Edit(int id) {
   // code snipped
   // this is invoked when viewing the edit page
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formValues) {
   // code snipped
   // this is invoked when POSTing data to the edit page
}

Differences between VARCHAR and NVARCHAR

VARCHAR (variable-length character string) is used to store a string of characters that can be as large as the page size for the database table containing the column (8,196 bytes with no row having more than 8,060 characters). VARCHAR columns are limited to 8,000 bytes. VARCHAR is stored as 8-bit data (1 byte per character). NVARCHAR is similar to VARCHAR but supports two-byte characters (UniCode). Therefore NVARCHAR columns can be used to store data that contains both English and non-English characters. NVARCHAR strings are stored in the database as UTF-16 (two bytes per character) and are converted to the codepage being used by the database connection on output (e.g. UTF-8). NVARCHAR uses two bytes for each character and can therefore only hold a maximum of 4,000 characters. An advantage of VARCHAR over NVARCHAR is that it takes up less space per row. The disadvantage is that you canot store non-English characters.

A note on SQL Server 2005

SQL Server 2005 introduced the MAX identifier which allows columns to go beyond the 8000 character limit and to store up to 2^31-1 (around 2 GB). NB: you still cannnot specify a size greater than 8000 characters (e.g. VARCHAR(12000)) but you need to use MAX (e.g. VARCHAR(MAX) or NVARCHAR(MAX)).

Tuesday 8 September 2009

What are NHibernate Projections

From NHibernate in action:
"Projection is the operation of choosing columns of a table and eliminating duplicate rows from the result. In SQL, the columns to be included are listed in the select clause." - NHibernate in Action, p.381
From the NHibernate documentation:
The class NHibernate.Expression.Projections is a factory for IProjection instances. We apply a projection to a query by calling SetProjection().
IList results = session.CreateCriteria(typeof(Cat))
.SetProjection( Projections.RowCount() )
.Add( Expression.Eq("Color", Color.BLACK) )
.List();
List results = session.CreateCriteria(typeof(Cat))
.SetProjection( Projections.ProjectionList()
.Add( Projections.RowCount() )
.Add( Projections.Avg("Weight") )
.Add( Projections.Max("Weight") )
.Add( Projections.GroupProperty("Color") )
)
.List();
In relational terminology, projection is defined as taking a vertical subset from the columns of a single table that retains the unique rows.
Tuesday 8 September 2009

HQL vs NHibernate Criteria API

HQL offers the benefits of literal SQL:
  • Very flexible
  • The only way to express some complex queries
But also the negatives - no compile-time syntax checking.
The Criteria API:
  • Provides compile-time syntax checking
  • Intellisense when working with Visual Studio

The difference between NHibernate Get and Load

If no row with the given identifier exists in the database the Get() or Get<>() method returns null.
In the case of Load() or Load<>() if the object can't be found by the given identifier an exception is thrown. Load() or Load<>()never returns null.
If you are using lazy loading the Load() or Load<>()may return a proxy instead of a real persistent instance.
Get() or Get<>() never returns a proxy because it must return
null if an entity with the given identifier doesn’t exist.
Use Load() or Load<>() if you’re certain the persistent object exists and nonexistence would be considered an error. If you aren’t certain that the entity exists use Get() or Get<>() and test for null.