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
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:
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
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. <).
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>
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.
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>
<object id="myGenericObject"
type="GenericsPlay.ExampleGenericObject<GenericDictionary<int , string>>, GenericsPlay" />
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
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