In the pass week, I have been watching iPhone Application Programming classes offered by Stanford University. I read a news on AppleInsider about Free Stanford iPhone dev podcasts downloaded 1 million times. Then I started the course.
Now I have watched 9 classes, one day a class during week days and two classes one day last weekend. It is really good program. I started to learn iPhone programming last year. I got iPhone SDK 2.0. I went to Apple's Dejavascript:void(0)veloper web page on iPhone. During evenings, I have read all the SDK documents and tried to use XCode to study some example applications. All those laid great foundation for me. This makes much easy for me to understand Object-C and Cocoa. I think after completion of the course, I am ready to put my hands on iPhone applications. I am really exited about this new journey!
Tuesday, May 26, 2009
iPhone Dev Classes by Stanford U
Posted by D Chu at 8:51 PM 0 comments
Labels: iPhone Applications, Mac
Monday, May 18, 2009
Dependency Injection and StructureMap (4)
In addition to the methods of dependency mapping described in my previous blog, SM provides several other alternative methods to describe the DM.
I use two common methods to specify how instances are created. One is IsThis() and another is ConstructedBy(). The first method takes one parameter as instance and the later one takes function name as parameter. The function returns an instance. Of course, you may create an instance and pass it by the first method. However, the instance must be a none-null instance, while the second method with function may return a null as DM.
For example, if ILog's mapping to instance is a LogToFile class:
public class LogToFile {
public LogToFile(
string file,
TextWriter standardOutput,
TextWriter errorOutput) { ... }
}
In the Registry class' CTOR, the DM then is described as:
internal class SMRegistry : Registry
{
private Configuration _config;
public SMRegistry(Configuration config)
{
_config = config;
ForRequestedType<ILog>().CacheBy(InstanceScope.Hybrid).
TheDefault.Is.ConstructedBy(GetLog);
...
}
private ILog GetLog()
{
ILog instance;
TextWriter writer1 =
_config.StandardOutput ? Console.Out : null;
TextWriter writerErr =
_config.ErrorOutput ? Console.Error : null;
instance = new LogToFile(_config.logFile,
wrtier1, writer2);
return instance;
}
}
where config is an instance of Configuration class which is loaded from an XML file. The LogToFile class CTOR takes a file name as log file name, and additional two TextWriter parameters as standard output and error output. The private function GetLog() is passed to ConstructedBy() to map an instance of ILog.
The above Registry can also be coded in this way:
internal class SMRegistry : Registry
{
private Configuration _config;
public SMRegistry(Configuration config)
{
_config = config;
ForRequestedType<TextWriter>.CachedBy(InstanceScrop.Hybrid).
TheDefault.Is.ConstractedBy(GetTW()).
WithName(LogToFile.StandardOutPutName);
ForRequestedType<TextWriter>.CachedBy(InstanceScrop.Hybrid).
TheDefault.Is.IsThis(Console.Error).
WithName(LogToFile.ErrorName);
ForRequestedType<ILog>().CacheBy(InstanceScope.Hybrid).
TheDefault.Is.OfConcreteType<LogToFile>().
ConstructedBy(GetLog);
...
}
private ILog GetLog()
{
return new LogToFile(_config.LogFile,
ObjectFactory.GetNamedInstance<TextWtiter>(
LogToFile.StandardOutPutName),
ObjectFactory.GetNamedInstance<TextWtiter>(
LogToFile.ErrorName));
}
private TextWriter GetTW()
{
return
_config.StandardOutput ? Console.Out : null;
}
}
This example shows how to use IsThis() method for an instance. LogToFile.StandardOutputName and LogToFile.ErrorName are constants defined within LogToFile class.
Here you can see SM's Registry DSL provides much flexible way to describe DMs.
Posted by D Chu at 7:41 PM 0 comments
Labels: C#, Design Pattern
Another Example of Fluent Interface
As in my previous blog posts, Fluent Interface pattern makes codes very simple and easy to read. The key point of FI is to define a class with methods returning a type of the class itself. As a result, you can continue to call its methods to manipulate data within the class. I have seen this pattern in jQuery and Dojo.
Normally, we define a class with a constructor to initialize its data members when an instance is created, and all those data members are not editable or no setters are defined. As a result, the class has its limitation only for one set of cases. If you want to define different set of data with manipulation by methods, you have to recreate objects again.
With FI pattern, here is another example to define a class to handle various data cases. Instead of passing data through CTOR, you can set data by using a method and the the return type of the class is the class itself, for example:
class MyFICalc {
private int _result;
private int _leftVal;
private int _rightVal;
public MyFICalc SetData(int val1, int val2) {
_leftVal = val1;
_rightVal = val2;
return this;
}
...
}
An instance is created by its default CTOR and data are set by the method SetData(). The method SetData() return a reference to itself. With this structure, further methods on data are defined to get expected result.
For example, I define a set of calculations:
int Add() {
return _leftVal + _rightVal;
}
int Subtract() {
return _leftVal - _rightVal;
}
int Multiply() {
return _leftVal * _rightVal;
}
Here are some example of uses:
int result;
MyFICalc calc = new MyFICalc();
result = calc.SetData(2, 3).Add(); // 5
result = calc.SetData(300, result).Subtract(); // 295
result = calc.SetData(result, 4).Multiply(); // 1180
Of course, this is a very simple example. In practice in one of data reading from database case, I have used FI in this manor in a loop for each row to set data and then continue to update data based on business logic. In this way, I would not need to constantly create instances. I just reuse my instance to set data and to get my result.
Posted by D Chu at 10:39 AM 0 comments
Labels: C#, Design Pattern
Wednesday, May 13, 2009
Dependency Injection and StructureMap (3)
SM uses Fluent Interface(FI) to describe dependency mapping relationships. The FI description is to read and straightforward. You may find out various ways to describe the dependency mapping(DM) relationships. Personally, I prefer to use FI in the following format:[For a required type].[Use a cache mechanism].[Map to a specific type]
The first part is normally for an interface type, but it can be concrete class type. The caching method is an enum type. It covers almost all the cases such new instance per request, singleton, one instance within a thread, HttpContext, HttpSession and more, see SM's documentation on Scroping and Lifecycle Management for detail information.
For the example case as described in the previous blog, here are the codes to describe ILog dependency mapping:
public class SMRegistry : Registry
{
public SMRegistry (
Configuration config)
{
ForRequestedType<ILog>().
CacheBy(StructureMap.Attributes.InstanceScope.Singleton).
TheDefault.Is.OfConcreteType<Logtofile>().
WithCtorArg(LogToFile.CtorArgFile).EqualTo(config.FileName).
WithCtorArg(LogToFile.CtorArgLogFlags).EqualTo(config.LogFlags);
...
}
}
Where
config
is an instance of Configuration
class. This instance contains configuration (loaded from xml file) to be passed to concrete instances.ILog
interface is mapped to class LogToFile
. This class CTOR takes two primitive string parameters one for file name and another as log flags. Here you can specify the primitive parameters using WithCtorArg(...).EqualTo(...)
pattern. Notice that the parameter name in WithCtorArg
has to be exactly as same as the one used in the CTOR and it is case-sensitive. I prefer to define a public const in CTOR's class.I want to skip the dependency mappings for IDataReader, IDataProcessor and IDataWriter. You can image continuing to do similar mappings for them. I'll discuss how to use SM's Registry to do mappings in a structured chain manor.
Now let's look at how to define DM for IProcessControl to a concrete class in the SMRegistry' CTOR:
ForRequestedType<IProcessController>().
CacheBy(StructureMap.Attributes.InstanceScope.Hybrid).
TheDefault.Is.OfConcreteType<ProcessController>().
WithCtorArg(ProcessContoller.CtorArgID).EqualTo(config.ID);
That's it. Recall that ProcessController's CTOR has five parameters, but only one is primitive type. Other four are instances as interface types. Those interfaces can be defined in a similar way as ILog. As a result, SM has the knowledge to inject concrete instances for those interface parameters. As I said before, you don't need to create instances in your application, you just tell SM the DMs and how. SM will inject instances for you.
If a CTOR's parameter has one concrete class parameter, you can still implement the similar way to do DM. I'll explain it later.
Posted by D Chu at 8:34 PM 0 comments
Labels: C#, Design Pattern
Sunday, May 10, 2009
Dependency Injection and StructureMap (2)
As I mentioned in my previous blog, Registry DSL is a recommended way to configure DI mappings by StuctureMap. StructureMap introduces Registry class which is normally used as a base class for customizing DI mapping definitions.
To start up, you need to define a class with Registry class as base. In the class' constructor, what you need to do is just to define dependencies. In StructureMap terms, the dependencies are defined as mapping PluginFamilies to Plugins. PluginFamilies are normally interfaces, but they can be any classes. Plugins, on the other hand, are plug-able classes corresponding to PluginFamily interfaces or classes. Here is a simple example:
internal class SMRegistry : Registry
{
public SMRegistry()
{
ForRequestedType<IProcessController>().
CacheBy(StructureMap.Attributes.InstanceScope.Singleton).
TheDefault.Is.OfConcreteType<Processcontroller>();
}
}
As you can see, the pattern is very simple and easy to read: for a required interfase or class, specify a cache mechanism, and the mapped class. StructureMap uses Fluent Interface patten to define dependencies. The above codes map IProcessController interface to a concrete class ProcessController. This class is ready for use. As in my previous blog example, the class can be loaded as a Registry instance by ObjectFactory.Add() method.
After the loading, SM has the knowledge of how to create concrete class ProcessController for IProcessController. You would not need to worry about when and how to create the concrete instance in your application. SM and Registry takes care of when and how. Since interfaces are used in your application, the application does not aware the implementation classes and what they are. This decoupling strategy allows you to focus on business logic implementation and makes it so easy to to update implementation libraries or to plug in a different implementation class without compiling your whole application. To update or fix bugs implementation classes or libraries, only those classes or libraries need to be compiled; to plug in different implementations, only the customized Registry class or libraries need to be recompiled.
The above example is based on the assumption that the class PocessController has only one default construtor, i.e., the constructor with no parameters. How about the cases with parametrized CTOR? SM provides similar Fluent Interface APIs for you.
For example, the following codes show the ProcessController class' CTOR with several parameters, and a LogToFile class which is used as a parameter:
public class ProcessController : IProcessController
{
public ProcessController(
int id,
ILog log,
IDataReader dataReader,
IDataProcessor dataProcessor,
IDataWritter dataWriter)
{ ... }
...
}
public class LogToFile : ILog
{
public LogToFile(
string file,
string flags)
{...}
...
}
I'll show you how to use SM to define their dependencies in a Registry class in the next blog.
Posted by D Chu at 8:53 PM 0 comments
Labels: C#, Design Pattern
Wednesday, May 06, 2009
Dependency Injection and StructureMap (1)
Recently I have been working a project with DI and StructureMap. The concept is not new but StructureMap was new for me. I did not take too long for me to understand how to use it, and soon I fall in love with SM.
The application is kine of reading data, processing data and finally writing data. The data are mostly from database such as Microsoft SQL or Oracle db. The processing part is based on business requirement. The destinations of data various from database, text files, emails or reports. There are many process in the same pattern. Then I decided to break the process into three parts as interfaces: IDataReader, IDataProcess and IDataWriter. On top of these three is the manager IProcessController. For different applications, this pattern can be repeated again and again by injecting implementation parts.
I did some research on DI framework. There are many great frameworks available, such as Spring.Net, Castle Project's Windsor Container, and Microsoft's MEF. All of them are open source frameworks. However, I find out that SM is only focused on DI and it does it very well.
I first tried it based on XML configuration. It is really straightforward. However, soon I found out that there is a better way to do it: Registry DSL(domain specific language) to make mapping between interface and class(actually it can also do for class to class). Think the Registry DSL as XML configuration, even it is done in .Net such as C#. Not only this provides a mush secure mapping, but it also provides much powerful ways to achieve DI which would be very hard to do in XML. Since the mapping is done within assembly, I think the performance should be much better than loading XML configuration files. According to SM, Registry DSL is a recommended way to configure DIs.
XML configuration files contains only PluginFamilies and Pugins logic. I also do the DI configuration in a separate assembly library project. My application can only see the interface libraries, domain class libraries, some commonly used libraries such as tools and .Net framework libraries, and the Registry DSL library:
The above is a slide show in my presentation on a demo case. ProcessDemoSM is the SM engine to load DI mappings to SM framework. ProcessDemoSM library sees all the interfaces and the libraries where implementation classes to be mapped. The application does not know the concrete classes. This makes the swap of implementations much easy and simple!
With the xxxSM project, there two basic classes, for example, SMForDemoApp (public class) and SMRegistry (based on Registry and internal class, ie, not visible to the outside of the assembly). Here is the example of SMForDemoApp class:
using StructureMap.Configuration.DSL;
public static class SMForDemoApp
{
private static bool _registered;
private static Configuration _configuration;
public static void InitializePlugins(
string configFile)
{
if (!_registered)
{
// Get configurtion information
_configuration = GetConfigInstance(configFile);
// Create Registry from this assembly
Registry registry = new SMRegistry(_configuration);
ObjectFactory.Initialize(x =>
{
x.AddRegistry(registry);
}
);
}
}
T GetInstance<T>() where T: class
{
T instance = null;
if ( typeof(T) == typeof(IProcessController) )
{
instance = ObjectFactory.GetInstance();
}
return instance;
}
}
The static class contains two private data members. _registered is straightforward. This guaranties SMRegister class is created only once. Within the class, it will load all the DI mappings to SM framework. The second one is a customize Configuration class. The class contains all the application information which are needed for instantiating implementation classes. In this example case, I store the configuration information in a file, eitehr JSON or XML file.
The interface InitializePlugins() is used to load Registry instances to SM framework. Here MSRegistry is derived from Registry class.
The method GetInstance<T>() returns an instance of generic type from SM framework. I make this method as generic so that if you need more than one types of instances, you can use this method.
The SM assembly is only referenced in this project. In my application, I don't need to add SM reference any more. I only need to add reference to this project or library. This library is like a wrapper class. It provides enough interfaces to instantiate DIs mappings to SM framework and method to get required instances back. Normally T type is by interface. A client or user does not what implementation class is mapped to. If you need to do different mapping, the only change is this library. You may think this library as SM's XML mapping file.
Here is an example in my console application, SMForDemoApp.
static main(string[] args)
{
SMForDemoApp.InitializePlugins();
IProcessController controller =
SMForDemoApp.GetInstance<IProcessController>();
controller.Start();
}
The console application is very simple. It gets an instance of IProcessControler and
calls Start() method to start process. The DI mapping is done within SMForDemoApp which relies on SM to load mapping. In the implementation class(IProcessController) uses many interface instances as well. SM will magically create instances for you, and all the instances will be injected to your implementation classes through constructor or property. You would not need to worry about how to create instances and pass instances in your implementation classes. You just concentrate on your implementation business logic.
The next thing I'll talk is about Registry class. SMRegistry class is based on SM's Registry class. In my next blog, I'll continue on the SMRegistry class.
Posted by D Chu at 7:27 PM 1 comments
Labels: C#, Design Pattern