|
|
前面写了一篇 Unity入门。写的比较仓促,所以东西比较粗糙,正如 戏水3 所说,没起到入门的作用。
本文就从 Unity中的QuickStart中关于StopLight的例子描述下Unity在程序开发中如何使用吧。
摘要:
交通灯Demo主要介绍如何在你的应用程序中使用Unity,用户界面是一个比较简单的WinForm程序,旨在显示
交通灯的示意,红黄绿,你可以设置它们依次显示的周期。 Form窗体界面如下图:
类关系图如下图:
向Unity容器注册服务:
在此Demo中主要使用了2个Service,即注册实现两个接口的服务。具体事例类
容器根据需要自动创建实例。
主要两个接口是 ILoger,IStoplightTimer ,ILoger具体实现 TraceLogger,NullLogger
IStoplightTimer 实现 RealTimeTimer
Code:
我们借用Unity,即可以在容器中注册这两个服务:
这样我们就在容器中建立了两个关系映射,即ILogger的实例TraceLogger 和
IStoplightTimer的实例 RealTimeTimer。
注意:以上说的实例还不够确切,只是一个关系映射,如果我们从容器中想要使用ILogger时,通过Resolve时,容器此时才会生成
ILogger的TranceLogger的实例。
在容器中注册了两个接口的映射关系后,我们还需要为我们的程序依赖注入一个
子对象或者暴露一个入口供我们去运行这个程序,即还要有用户界面供外部调用。
继承Windows.Form 的StoplightForm就做我们的主显示窗体吧,为确保所有的对象都是依赖注入的,我们就可以在
Program 类中通过Resolve方法生成StoplightForm,并显示。
Code:
Application.Run(container.Resolve<StoplightForm>());
使用MVP模式:
当Demo运行时,它会加载我们的用户接口,StoplightForm 窗体,该窗体实现了MVP模式, MVP模式具体如何实现在此不做多讲,有兴趣的可以去
TerryLee 的博客 ,那里面有详细的介绍。
实现了MVP模式,那么它就需要暴露一个 属性(类对象)给调用者。这个类对象即是 StoplightPresenter,这Form窗体使用属性的
Setter方法获取StoplightPresenter 实例设置presenter。
public partial class StoplightForm : Form, IStoplightView
{
private StoplightPresenter presenter;[Dependency]
public StoplightPresenter Presenter
{
get { return presenter; }
set
{
presenter = value;
presenter.SetView(this);
}
}
...
注意: 必须确保Untity在创建StoplightForm 之前创建Presenter,这样依赖注入的类才能被注入,生成StoplightPresenter。
通过属性 Setter注入业务组件:
private Stoplight stoplight;
[Dependency]
public Stoplight Stoplight
{
get { return stoplight; }
set { stoplight = value; }
}
同样 Presenter 也需要一个依赖对象StoplightSchedule ,Code:
private StoplightSchedule schedule;
[Dependency]
public StoplightSchedule Schedule
{
get { return schedule; }
set { schedule = value; }
}
至此,此Demo需要依赖注入的对象已完成,在Unity已经成功生成了个对象之间的映射关系。
后注:
Demo旨在演示通过Unity依赖注入对象,来实现我们想要的功能。 比如ILogger。TraceLogger是我们在程序初期就已经设计好了,
并确定使用它。那么我们在一开始就可以通过Untity的RegisteType进行关系映射。 但是 有时需求并不是在一开始就能取诶的那个。
比如,在后期程序中的ILogger接口我们需要使用FileLogger记录,那我们就要重新修改代码,重新编译了。
其实Untity中我们可以通过 配置文件 进行动态注册。需要使用哪种日志直接通过修改配置文件就可以了。
下篇将介绍如何使用配置文件进行Unity动态注册及映射关系。
不足之处,请包涵。谢谢
Demo代码:下载
Microsoft 的 P&P 团队在发布了 Unity Application Block 1.2 - October 2008。
描述
Unity 应用程序块(Unity)是一个轻量级、可扩展的依赖注入容器,支持构造函数、属性和方法调用注入。它为开发人员提供了如下好处:
常见场景
除了单独解决横切关注点如日志、认证、授权、缓存和异常处理的组件以外,现代业务系统通常由定制的业务对象和在应用程序中完成特殊的或者一般的任务的组件组成。
成功构建这样的应用程序的关键是获得解耦的或者极度松耦合的设计。松耦合的应用程序更加灵活、更加易于维护。同时在开发期间进行测试,可以模拟对象的桩(轻量级模拟的实现),这增强了实质的依赖。例如,数据库连接、网络连接、ERP 连接和富用户接口组件。
依赖注入是一种用于构建松耦合应用程序的主要技术。它提供了处理对象间依赖的方法。例如,一个处理用户信息的对象可能依赖于访问数据存储、验证信息和检查用户是否被授权执行更新的其他对象。依赖注入技术可以确保用户类正确的初始化及组装所有这些对象,特别是依赖是抽象的地方。
使用容器可以有很多好处,但它会改变应用程序的设计方式,尤其适合于基于组件的开发,朋友们可以有选择的使用它。
参考了Dorian Deng 和 TerryLee的博客文章。 发现1.2版本和先前Terre Lee 发布那篇文章使用的 Register<> 和Get<>方法现在已经过时,取而代之的是
RegisterType <> 和 Resolve<> ,故将Terry Lee大哥的文章整理了下。
首先编写 这几个类
接口ILogger
public interface ILogger
{
void Write(string message);
}
FlatFileLogger类
public class FlatFileLogger : ILogger
{
public void Write(string message)
{
Console.WriteLine(String.Format("Message:{0}", message));
Console.WriteLine("Target:FlatFile");
}
}
DatabaseLogger类
public class DatabaseLogger : ILogger
{
public void Write(string message)
{
Console.WriteLine(String.Format("Message:{0}",message));
Console.WriteLine("Target:Database");
}
}
然后,安装Unity Application Block 1.2.msi 。地址在http://www.microsoft.com/downloads/details.aspx?FamilyId=2C8B79E7-AE56-4F90-822E-A1E43C49D12E&displaylang=en可以下载。
新建工程,然后添加untity的引用
然后在 主程序中 执行
class Program
{
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<ILogger, FlatFileLogger>();
ILogger logger = container.Resolve<ILogger>();
logger.Write("TerryLee");
Console.ReadLine();
}
}
运行结果:
至此 一个untity 的程序基本成功。
备注:
untity容器可以包含 Container-Configured Registration of Types 抽象接口式
IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<IMyService, CustomerService>();
IMyService myServiceInstance = myContainer.Resolve<IMyService>();
也可以在容器中包含 Container-Configured Registration of Existing Object Instances 存在实例
IUnityContainer myContainer = new UnityContainer();
LoggingService myExistingObject = new LoggingService();
myContainer.RegisterInstance<IMyService>(myExistingObject);
IMyService myServiceInstance = myContainer.Resolve<IMyService>();
灵活性比较突出,对于解耦和程序的松散型提供了非常好的支持。
入门篇到此为止,下篇继续分享 untity在开发中实际的应用。
1、CASE 某个字段 WHEN 某个值 THEN 赋予某个值 ELSE 赋予另外个值 END
2、或者: CASE 某个字段 WHEN 某个值 THEN 赋予另外个值 END
3、注意:
例子:
--1
SELECT * FROM SY_CORP_PRODUCT
WHERE
CASE N_CORP_CODE WHEN 969 THEN 123 ELSE N_CORP_CODE END = 969
;
--2
SELECT * FROM SY_CORP_PRODUCT WHERE N_CORP_CODE = 123;
--3
SELECT * FROM SY_CORP_PRODUCT WHERE N_CORP_CODE = 969;
1的数据集=2的数据集U3的数据集