近几天看了有关 IoC 的文章后,觉得很不错,于是做了一个简单的小程序,分享一下心得,而如果使用一个完整的 IoC 构件如 Castle 无疑会有更强大功能,不过对于未接触过这个概念的人来说无什么帮助.
程序演示: 提供一个 Manager 类给操作者,操作者能取得其资讯(或操作其做某些动作).Manager 有 2 种技能和 2 种身体状态.
程序目的: 操作者不用知道 Manager 的实际组合和建立动作,就可以直接使用,而 Manager 能使用 XML 做设置,使其在运行时提供不同的功能给予操作者,而程序不必重新编译.
[STAThread]
static void Main(string[] args)
{
ServiceContainer sc = new ServiceContainer();
Manager mg = (Manager)sc.RequestService( Manager.strClassName );
if( mg == null )
return;
Console.WriteLine( "{0}", mg.GetInfo() );
Console.Read();
}
static void Main(string[] args)
{
ServiceContainer sc = new ServiceContainer();
Manager mg = (Manager)sc.RequestService( Manager.strClassName );
if( mg == null )
return;
Console.WriteLine( "{0}", mg.GetInfo() );
Console.Read();
}
using System;
using System.IO;
using System.Xml;
using System.Collections;
namespace Demo
{
//******************************** Room ***************** (A)
public interface IRoomSkill
{
string GetName();
}
public class ClearRoom : IRoomSkill
{
public const string strClassName = "ClearRoom";
public string GetName()
{
return "room skill is: " + "清洁";
}
}
public class FixRoom : IRoomSkill
{
public const string strClassName = "FixRoom";
public string GetName()
{
return "room skill is: " + "修理";
}
}
//******************************** Body ***************** (B)
public interface IBody
{
string GetName();
}
public class Strong : IBody
{
public const string strClassName = "Strong";
public string GetName()
{
return "body: " + "强壮";
}
}
public class Thin : IBody
{
public const string strClassName = "Thin";
public string GetName()
{
return "body: " + "瘦弱";
}
}
//********************************************************* (C)
public class Manager
{
IRoomSkill m_IRoomSkill;
IBody m_IBody;
public const string strClassName = "Manager";
public Manager()
{
}
// 建构 注入
public Manager(IRoomSkill room,IBody roomOwner)
{
m_IRoomSkill = room;
m_IBody = roomOwner;
}
public bool AddComponent(object obj,string strInterfaceClassName)
{
if( obj == null )
return false;
if( strInterfaceClassName == typeof( IRoomSkill ).Name.ToString() )
{
m_IRoomSkill = (IRoomSkill)obj;
return true;
}
else if( strInterfaceClassName == typeof( IBody ).Name.ToString() )
{
m_IBody = (IBody)obj;
return true;
}
return false;
}
public string GetInfo()
{
if( m_IRoomSkill == null || m_IBody == null )
return null;
return string.Format( "manager info, {0}, {1} ",
m_IRoomSkill.GetName(),
m_IBody.GetName() );
}
}
//********************************************************* (D)
public class ClassInfo
{
public string strInterfaceClassName;
public string strComponentName;
}
//********************************************************* (E)
public class ServiceContainer
{
public object RequestService(string strClassName)
{
if( strClassName == Manager.strClassName )
{
ArrayList ar = ReadXMLClassInfo( strClassName );
if( ar == null || ar.Count < 1 )
return null;
Manager mg = new Manager();
foreach(ClassInfo ci in ar)
{
object obj = ObjectBuilder( ci.strComponentName );
if( obj == null )
continue;
mg.AddComponent( obj, ci.strInterfaceClassName );
}
return mg;
}
return null;
}
object ObjectBuilder(string strClassName)
{
if( strClassName == ClearRoom.strClassName )
return new ClearRoom();
else if( strClassName == FixRoom.strClassName )
return new FixRoom();
else if( strClassName == Strong.strClassName )
return new Strong();
else if( strClassName == Thin.strClassName )
return new Thin();
return null;
}
ArrayList ReadXMLClassInfo(string strClassName)
{
string strFile = strClassName + ".xml";
if( File.Exists( strFile ) == false )
{
Console.WriteLine( "file not find" );
return null;
}
XmlTextReader xtr = new XmlTextReader( strFile );
ArrayList ar = new ArrayList();
string strStartFlag = null;
while( xtr.Read() )
{
if( xtr.NodeType == XmlNodeType.Element )
{
strStartFlag = xtr.Name;
}
else if( xtr.NodeType == XmlNodeType.Text )
{
if( strStartFlag != null && strStartFlag.Length > 0 )
{
ClassInfo ci = new ClassInfo();
ci.strInterfaceClassName = strStartFlag;
ci.strComponentName = xtr.Value;
ar.Add( ci );
strStartFlag = null;
}
}
}
return ar;
}
}
//*********************************************************
} // namespace end
using System.IO;
using System.Xml;
using System.Collections;
namespace Demo
{
//******************************** Room ***************** (A)
public interface IRoomSkill
{
string GetName();
}
public class ClearRoom : IRoomSkill
{
public const string strClassName = "ClearRoom";
public string GetName()
{
return "room skill is: " + "清洁";
}
}
public class FixRoom : IRoomSkill
{
public const string strClassName = "FixRoom";
public string GetName()
{
return "room skill is: " + "修理";
}
}
//******************************** Body ***************** (B)
public interface IBody
{
string GetName();
}
public class Strong : IBody
{
public const string strClassName = "Strong";
public string GetName()
{
return "body: " + "强壮";
}
}
public class Thin : IBody
{
public const string strClassName = "Thin";
public string GetName()
{
return "body: " + "瘦弱";
}
}
//********************************************************* (C)
public class Manager
{
IRoomSkill m_IRoomSkill;
IBody m_IBody;
public const string strClassName = "Manager";
public Manager()
{
}
// 建构 注入
public Manager(IRoomSkill room,IBody roomOwner)
{
m_IRoomSkill = room;
m_IBody = roomOwner;
}
public bool AddComponent(object obj,string strInterfaceClassName)
{
if( obj == null )
return false;
if( strInterfaceClassName == typeof( IRoomSkill ).Name.ToString() )
{
m_IRoomSkill = (IRoomSkill)obj;
return true;
}
else if( strInterfaceClassName == typeof( IBody ).Name.ToString() )
{
m_IBody = (IBody)obj;
return true;
}
return false;
}
public string GetInfo()
{
if( m_IRoomSkill == null || m_IBody == null )
return null;
return string.Format( "manager info, {0}, {1} ",
m_IRoomSkill.GetName(),
m_IBody.GetName() );
}
}
//********************************************************* (D)
public class ClassInfo
{
public string strInterfaceClassName;
public string strComponentName;
}
//********************************************************* (E)
public class ServiceContainer
{
public object RequestService(string strClassName)
{
if( strClassName == Manager.strClassName )
{
ArrayList ar = ReadXMLClassInfo( strClassName );
if( ar == null || ar.Count < 1 )
return null;
Manager mg = new Manager();
foreach(ClassInfo ci in ar)
{
object obj = ObjectBuilder( ci.strComponentName );
if( obj == null )
continue;
mg.AddComponent( obj, ci.strInterfaceClassName );
}
return mg;
}
return null;
}
object ObjectBuilder(string strClassName)
{
if( strClassName == ClearRoom.strClassName )
return new ClearRoom();
else if( strClassName == FixRoom.strClassName )
return new FixRoom();
else if( strClassName == Strong.strClassName )
return new Strong();
else if( strClassName == Thin.strClassName )
return new Thin();
return null;
}
ArrayList ReadXMLClassInfo(string strClassName)
{
string strFile = strClassName + ".xml";
if( File.Exists( strFile ) == false )
{
Console.WriteLine( "file not find" );
return null;
}
XmlTextReader xtr = new XmlTextReader( strFile );
ArrayList ar = new ArrayList();
string strStartFlag = null;
while( xtr.Read() )
{
if( xtr.NodeType == XmlNodeType.Element )
{
strStartFlag = xtr.Name;
}
else if( xtr.NodeType == XmlNodeType.Text )
{
if( strStartFlag != null && strStartFlag.Length > 0 )
{
ClassInfo ci = new ClassInfo();
ci.strInterfaceClassName = strStartFlag;
ci.strComponentName = xtr.Value;
ar.Add( ci );
strStartFlag = null;
}
}
}
return ar;
}
}
//*********************************************************
} // namespace end
Manager.XML: (skill: ClearRoom or FixRoom, body: Strong,Thin )
<?xml version="1.0" encoding="utf-8" ?>
<Manager>
<IBody>Strong</IBody>
<IRoomSkill>FixRoom</IRoomSkill>
</Manager>
<Manager>
<IBody>Strong</IBody>
<IRoomSkill>FixRoom</IRoomSkill>
</Manager>
IoC 容器优势: 分离使用者和建造者,使其两不相关,提供动态类组合.
依赖注入(Dependency Injection)优势: 使提供的操作类只和接口相关,使类只对接口编程,不用去关心其他类,能动态注入元件,增加新元件时模块改动很少.
注: 除了可以使用 XML 外也可以使用任意资源,而使用 XML 做中介最后读取并放在内存中速度会更快,另外 ObjectBuilder() 建立类的方法及 AddComponent() 的条件式也不是最好的做法.不过和主题无关也就不多写了.
程序文件Demo.zip: https://files.cnblogs.com/slider8jet/Demo.zip

浙公网安备 33010602011771号