Saturday, July 08, 2017

Type Erasure

Say that I have a view model that has a reference to a data source object generated by another object like a factory. In my view model I would have a property that is typed as AnyDataSource. I also have a property that is of type FRCDataSource, this is the object that will be wrapped in the AnyDataSource object.

class AddToDoViewModel {
    var dataSource : AnyDataSource<Item>!
    var frcDataSource : FRCDataSource<Item>!

FRCDataSource is defined as :

class FRCDataSource<T: NSManagedObject> : DataSourceProtocol {

    var fetchedResultsController : NSFetchedResultsController<T>!

    init(fetchedResultsController: NSFetchedResultsController<T>) {
    self.fetchedResultsController = fetchedResultsController
    }
}

The FRCDataSource class is a wrapper around an NSFetchedResultsController type. The generic type constraint on FRCDataSource limits the type of T to be an object that derives from NSManagedObject. Also note that FRCDataSource is specialized by the same type as NSFetchedResultsController. To create an FRCDataSource we do the following in reloadData()

func reloadData() {
    self.frcDataSource = FRCDataSource(fetchedResultsController:self.fetchedResultsController)
}

We create an FRCDataSource, passing in the NSFetchedResultsController class property. Now our frcDataSource property is set to a FRCDataSource instance that internally stores a NSFetchedResultsController instance. In this case, I am creating an instance of FRCDataSource directly, although I could easily delegate this responsibility to another object which would create and return an FRCDataSource.

Once I’ve created an FRCDataSource object from the NSFetchedResultsController, I can now add a method that will create an AnyDataSource derived object and store it in the dataSource property of the view model:

func createDataSource<T: DataSourceProtocol>(dataSource: T) where T.DataSourceItem == Item 
{
    self.dataSource = AnyDataSource(dataSource)
}

The createDataSource() takes an object that adopts the DataSourceProtocol, creates an AnyDataSource object and sets the dataSource property. There are a few things to take note of here:

Once the data source is created we will have an AnyDataSource typed object that can be used in place of a DataSourceProtocol type.

Basically what we’ve done is create wrappers for two types


Thursday, December 20, 2007

Derived classes and events

Events are a useful feature of the C# language and allow for clients to be notified when the state of a server changes. You create an event by declaring it in the class that will raise the event:

public event EventHandler NotifyClient;

Here, I used the generic event template to eliminate the need to define a separate delegate. To register a callback method with the event, we do the following in the class that will receive the event notification from the class that raised the event:

message.NotifyClient += new EventHandler(message_NotifyClient);

static void message_NotifyClient(object sender, EventArgs e)
{
throw new Exception("The method or operation is not implemented.");
}

When the event is raised the message_NotifyClient method will execute. To raise the event we add the following to the class that raises the event:

protected virtual void OnNotifyClient(EventArgs e)
{
EventHandler handler = NotifyClient;

if (handler != null)
handler(this, e);
}

Here, we make a copy of the event since access to the event is not thread-safe (i.e. another thread could delete/modify the event before the if (handler != null) completes). When the client wants to raise the event, it does so by executing the OnNotifyClient method:

private void DoSomething()
{
// Do something...
OnNotifyClient(new EventArgs());
}

When OnNotifyClient is executed, the message_NotifyClient method is executed.

Derived classes and events
An event can only be raised from methods declare within the class that declared the event. So events declared in class A can only be raised from methods within class A. By default, events are not inherited by derived classes, so in the following base class definition:

public class Base
{
public event EventHander NotifyClient;
}

with the derived class definition

public class Derived : Base
{
private void DoSomething()
{
EventHandler handler = NotifyClient;

if (handler != null)
handler(this, new EventArgs());
}
}

The derived class will not have access to the NotifyClient event since the NotifyClient event was not declared in the Derived class. There are two ways to workaround this requirement:
You'll notice above that the OnNotifyClient method is declared with the virtual keyword. This allows the Derived class to override the OnNotifyClient method and access the NotifyClient directly. So, we could do this in the Derived class:

protected override void OnNotifyClient(EventArgs e)
{
EventHandler handler = NotifyClient;

if (handler != null)
handler(this, e);
}

protected void DoSomething()
{
// Do something Derived-class specific, then call OnNotifyClient
OnNotifyClient(new EventArgs());
}

The second approach is to declare the event virtual in the Base class, then override the event in the Derived class:

public class Base
{
public virtual event EventHandler NotifyClient;
...
}

public class Derived : Base
{
public override event EventHandler NotifyClient;

public void DoSomething()
{
EventHandler handler = NotifyClient;

// Here, we can access the NotifyClient directly since we've overridden access
if (handler != null)
handler(this, new EventArgs());
}
}

Which approach you take is up to you. Both approaches give the Derived class the flexibility to perform Derived-specific tasks around the decision to raise the event. It really comes down to which approach is preferred.

Wednesday, November 28, 2007




When the pros of using reflection outweigh the cons, you can take advantage of using it when iterating over properties of classes.  To help with debugging, you can override the ToString() of your classes to return a string that contains the name of any public properties along with their corresponding values:

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            Type t = this.GetType();

            PropertyInfo[] pInfo = t.GetProperties();

            sb.Append(t.ToString() + "\r\n");

            foreach (PropertyInfo p in pInfo)
            {
                string fmt = string.Format("{0} = {1}", p.Name, p.GetValue(this, null));

                sb.Append(fmt + "\r\n");
            }

            return sb.ToString();
        }

The function uses reflection to get the public properties of the class and it iterates over the collection of properties and builds a string that represents the state of the class.  The string returned from ToString() would look like this:

Property1 = Value1
Property2 = Value2
.
.
.

The PropertyInfo.GetValue() function takes two parameters; the first parameter is the reference to this, while the second parameter is an object array that is used when the PropertyInfo references an indexed property.  When using reflection to enumerate properties on a class that contains other classes, you must accomodate the case where a class might contain an indexed property:

public class Details
{
        public EDIProcess.Model.EstimateDetailType this[int index]
        {
            get { return (EDIProcess.Model.EstimateDetailType) DetailCollection[index]; }
        }
}

In this case, the Details class contains an indexer that is used to retrieve EstimateDetailType objects by index from the DetailCollection property.  You can use the GetValue() function and pass in an object array that contains a single entry that is the value of the offset into the collection, which will reference the indexed item at that position within the collection.

public class Details
{
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            try
            {
                Type t = this.GetType();
                string fmt;

                PropertyInfo[] pInfo = t.GetProperties();


                sb.Append(t.ToString() + "\r\n");

                foreach (PropertyInfo p in pInfo)
                {
                    if (p.Name == "Item")
                    {
                        for (int i = 0; i < Count; i++)
                        {
                            fmt = string.Format("{0} = {1}", p.Name, p.GetValue(this, new object[] { i }));
                            sb.Append(fmt + "\r\n");
                        }
                    }
                    else
                    {
                        fmt = string.Format("{0} = {1}", p.Name, p.GetValue(this, null));
                        sb.Append(fmt + "\r\n");
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
            }

            return sb.ToString();
    }
}

The items in bold represent the changes to support the indexed properties.  The Details class contains a DetailCollection class (which derives from ArrayList), and the Details class contains an indexer to retrieve an item from the collection as well as a property that returns the number of items stored in the collection.  The modification looks for a property named Item in the Details class, and it then retrieves the count of objects in the collection and for each object in the collection it calls the GetValue(), passing in a reference to the Details class (this) and a new object[] array that contains a single member that stores the integer value of the item within the collection.




Friday, September 21, 2007

Threading in C#

I found an interesting online resource on Threading in C#

Friday, November 03, 2006

On the project that I am leading, I ran across an interesting issue using a combination of a stored procedure and the ISNULL SQL function. If we have the following table definition:

CREATE TABLE [dbo].[TEST_TABLE] (
[Data] [varchar] (5) COLLATE Latin1_General_BIN NOT NULL
)


and this table contains a row that contains:

Data
=====

ABCDE


Now, if we have a stored procedure that updates the row called UpdateData:

CREATE PROCEDURE UpdateData
@Data varchar(3) = null
AS

Begin Tran
update TEST_TABLE
set Data = ISNULL(@Data, Data)
IF @@ERROR <> 0
Rollback Tran
else
Commit Tran

The stored procedure sets the @Data variable to null by defualt, otherwise it will use the value passed to it via the @Data variable. The update statement uses the ISNULL function to check if the @Data variable is the default value of null and if it is, then it should use the current value in the Data column on the table. If we call this stored procedure, without passing in the @Data parameter, the stored procedure will set the value of the @Data parameter to null, and this is what we'll get:

Data
=====
ABC


What happened, why did my data get truncated? Think about how the ISNULL function works, it sets the variable specified in the first parameter to the value of the variable specified in the second parameter if the first parameter is null. So, it should set the @Data variable to the value in the Data column. Also note that the stored procedure is implicitly creating the @Data variable in the procedure declaration and also note that the @Data variable has a width of 3 varchars instead of the 5 varchars in the TEMP_TABLE Data column declaration. Essentially what happens is that the ISNULL function sees that the @Data variable is null, reads the Data column from the table and then copies the value from the Data column into the @Data variable. Since the @Data variable is only 3 varchars wide, only 3 varchars are copied to it. The set clause then updates the Data column with these 3 varchars from the @Data variable. That's why the data gets truncated. So, the moral of the story is to make sure of the following:

Wednesday, October 04, 2006

SQL Server pseudo nested transactions

SQL Server 2000 does not support nested transactions. So, if we have the following two stored procedures:

SP1:

create procedure sp1
as

begin tran
exec sp2

if (@@error <> 0)
goto on_error

commit tran

on_error:
rollback tran



SP1:
create procedure sp2
as

begin tran
insert table values ('sp2')

if (@@error <> 0)
goto on_error

commit tran

on_error:
rollback tran


The rules for nested begin transactions is:
Basically, I think of nested transactions as really just one main transaction that could contain multiple time points where the state of the transaction (committed, rollback) can be modified.

When using the ADO.NET SqlTransaction object you need to be aware of how transactions are committed and rolled back. When the SqlTransaction.BeginTransaction method is executed, it implicitly executes the BEGIN TRAN SQL statement. Any SQL statements executed will then execute on this main transaction. If the SQL statements that are executed perform a commit or rollback, the main transaction is affected based on the rules above. There may be certain cases where a servere SQL error will cause the main transaction to rollback, and if the main transaction is created by the SqlTransaction.BeginTransaction method, when the exception is caught, you will need to check if the transacion was actually already rolled back before executing the SqlTransaction.Rollback method:


try
{
try
{
SqlTransaction txn = new SqlTransaction();

txn.BeginTransaction();

Data.CallSproc1();
Data.CallSproc2(); // throws an exception and rolls back the transaction
txn.CommitTransaction();
}
catch(SqlException ex)
{
txn.RollbackTransaction(); // If the transaction is already rolled back, this will throw an exception
}
}
catch(SqlException ex)
{
// Transaction was already rolled back, do something
}
}

Monday, October 02, 2006

NTLM Explained

If you want a good description of NTLM Authentication (Windows authentication), you can find a good resource here

This page is powered by Blogger. Isn't yours?