BareTail is a free utility for watching log tiles in real-time. It is basically like a UNIX tail command in a window:
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
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.Martin Fowler also has a few words of advice on this issue:
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."
"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.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:
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
"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
1. The left bracket () must be written using XML escape syntax (i.e. <).
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<int>, GenericsPlay">
<property name="Name" value="My Integer List"/>
</object>
Note the use of <.
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<,>" />
</typeAliases>
type="GenericsPlay.ExampleGenericObject<GenericDictionary<int , string>>, GenericsPlay" />
instead of:
<object id="myGenericObject"
type="GenericsPlay.ExampleGenericObject<System.Collections.Generic.Dictionary<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
-- 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
"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.
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
- Open the IIS MMC snap-in.
- View the properties for the webs site in question.
- Go to the Home Directory tab.
- Click Configuration...
- Add a new extension (.mvc).
- Map the extension to the aspnet_isapi.dll.
- Limit to the following verbs: GET,POST,HEAD,DEBUG.
- Uncheck the 'Check that file exists' and 'Script engine' checkboxes.
Thrive for Developers
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
... 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
Download from http://www.linqpad.net/.
Thursday, 10 September 2009
Setting ARITHABORT can affect query performance
"Terminates a query when an overflow or divide-by-zero error occurs during query execution.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 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."
If a query is running very slowly from code it is worth checking if ARITHABORT should be set to on.
UpdateModel() and TryUpdateModel()
[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
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
HQL vs NHibernate Criteria API
- Very flexible
- The only way to express some complex queries
- Provides compile-time syntax checking
- Intellisense when working with Visual Studio