现在的位置: 首页 > 综合 > 正文

Introducing Unity Application Block

2012年11月30日 ⁄ 综合 ⁄ 共 7657字 ⁄ 字号 评论关闭

Unity Block学习笔记

1 What's Unity?

1.1 轻量DI容器

1.1.1 traditional

1.1.1.1 constructor

1.1.1.2 setter

1.1.1.3 interface

1.1.2 Unity 扩展

1.1.2.1 property

1.1.2.2 method call

1.2 与其他EntLib的差异

1.2.1 可独立安装的DI机制

1.2.2 解决DI的途径

1.2.2.1 通过配置

1.2.2.2 通过代码动态注册

1.2.3 不依赖于EntLibCoreConfiguration部分

1.3 优势

1.3.1 简化对象的创建过程,尤其是层次型对象

1.3.2 借助横切方式,提供必要的抽象,对象创建的定义可以通过配置或运行时方式完成

1.3.3 将构造过程延迟到依据容器的配置

1.3.4 提供Service Locator功能

1.3.4.1 container保存位置

1.3.4.1.1 ASP.NET Session

1.3.4.1.2 ASP.NET Application

1.3.4.1.3 其他Client Store

2 Unity的常用情景

2.1 背景

2.1.1 由于业务的复杂性,现代软件进入基于组件的软件工程时代

2.1.2 包括业务处理组件、公共机制、还有一系列横切机制

2.1.3 必须采用松散耦合设计

2.1.4 但对象的创建过程往往又存在严格的依赖关系

2.2 常用的解决模式

2.2.1 IoC模式

Inversion of Control (IoC) pattern. This generic pattern describes techniques for supporting a plug-in architecture where objects can "look up" instances of other objects they require.

2.2.2 DI模式

Dependency Injection (DI) pattern. This is a special case of the IoC pattern and is an interface programming technique based on altering class behavior without the changing the class internals. Developers code against an interface for the class and use a container that injects dependent object instances into the class based on the interface or object type. The techniques for injecting object instances are interface injection, constructor injection, property (setter) injection, and method call injection.

2.2.3 Interception模式

Interception pattern. This pattern introduces another level of indirection. This technique places an object between the client and the real object. A proxy is used between the client and the real object. The client behavior is the same as interacting directly to the real object, but the proxy intercepts them and solves their execution by collaborating with the real object and other objects as required.

3 开发应用

3.1 环境要求

This topic describes the requirements for installing and using the Unity Application Block. It also discusses how you can extend and modify the application block using different versions of Visual Studio. The minimum requirements are the following:

 

Microsoft Windows XP Professional, Windows Server 2003, Windows Server 2008, or Windows Vista operating system

Microsoft .NET Framework 2.0, 3.0, or 3.5

Microsoft Visual Studio 2005 or Visual Studio 2008 development system (any of the following editions):

The Express Editions:

Visual Basic 2008 Express Edition

Visual C# 2008 Express Edition

Visual C++ 2008 Express Edition

Visual Web Developer 2008 Express Edition

Standard Edition

Professional Edition

Team Edition for Software Developers

Team Edition for Software Testers

Team Edition for Software Architects

Team Suite

The Unity Application Block solution and project files are all in Visual Studio 2005 format, and you can open them and modify them using Visual Studio 2005. The binary assemblies provided with the application block are targeted at version 2.0 of the .NET Framework. However, you can use the Unity Application Block in applications created with Visual Studio 2008 by setting a reference to the binary assemblies.

 

You can modify or extend the Unity Application Block using Visual Studio 2008. When you open a solution, Visual Studio 2008 will upgrade the projects to its format, and you can edit and compile the code to create assemblies targeted at version 3.5 of the .NET Framework. However, you will not be able to convert the projects back into Visual Studio 2005 format. Therefore, it is a good idea to work with a copy of the original solutions and projects.

 

3.2 构造类型实例

3.2.1 构造一个最简单的对象实例

       publicinterfaceIUser{ }

 

       publicclassUserA: IUser{ }

       publicclassUserB: IUser{ }

 

       publicclassObjectWithTwoProperties

       {

           objectobj1;

           objectobj2;

 

           [Dependency]

           publicobjectObj1

           {

               get{ returnobj1; }

               set{ obj1 = value; }

           }

 

           [Dependency]

           publicobjectObj2

           {

               get{ returnobj2; }

               set{ obj2 = value; }

           }

 

          publicvoidInjectInt(intmax)

           {

               this.max = max;

           }

 

           [InjectionMethod]

           publicvoidInjectString(stringmessage, intcount)

           {

               this.message = message;

               this.count = count;

           }

       }

 

       [TestMethod]

       publicvoidTestCreateInstanceByInterface()

       {

           IUnityContainercontainer = newUnityContainer();

           container.RegisterType<IUser, UserA>();

           IUseruserA = container.Resolve<IUser>();

           Assert.IsInstanceOfType(userA,typeof(UserA));

       }

 

       [TestMethod]

       publicvoidTestSetterInjection()

       {

           IUnityContainercontaienr = newUnityContainer();

           ObjectWithTwoPropertiestarget = newObjectWithTwoProperties();

           Assert.IsNull(target.Obj1);

           Assert.IsNull(target.Obj2);

 

           contaienr.BuildUp(target);

           Assert.IsNotNull(target.Obj1);

           Assert.IsNotNull(target.Obj2);

       }

3.2.2 为映射关系命名

publicinterfaceIUser

{

}

 

publicclassDefaultUser: IUser

{

}

 

publicclassUserA: IUser

{

}

 

publicclassUserB: IUser

{

}

 

[TestMethod]

publicvoidTestCreateDefaultTypeInstance()

{

    IUnityContainercontainer = newUnityContainer()

        .RegisterType<IUser, DefaultUser>()

        .RegisterType<IUser, UserA>("A")

        .RegisterType<IUser, UserB>("B");

    IUseruser = container.Resolve<IUser>();

    Assert.IsInstanceOfType(user,typeof(DefaultUser));

}

 

 

[TestMethod]

publicvoidTestCreateNamedTypeInstance()

{

    IUnityContainercontainer = newUnityContainer()

        .RegisterType<IUser, DefaultUser>()

        .RegisterType<IUser, UserA>("A")

        .RegisterType<IUser, UserB>("B");

    IUseruserA = container.Resolve<IUser>("A");

    Assert.IsInstanceOfType(userA,typeof(UserA));

    IUseruserB = container.Resolve<IUser>("B");

    Assert.IsInstanceOfType(userB,typeof(UserB));

}

3.2.3 构造一系列简单的对象实例

publicinterfaceIUser

{

}

 

publicclassDefaultUser: IUser

{

}

 

publicclassUserA: IUser

{

}

 

publicclassUserB: IUser

{

}

 

[TestMethod]

publicvoidTestCreateSeriesInstances()

{

    IUnityContainercontainer = newUnityContainer()

       .RegisterType<IUser, UserA>("A")

       .RegisterType<IUser, UserB>("B");

    IList<IUser> users = newList<IUser>(container.ResolveAll<IUser>());

    Assert.IsInstanceOfType(users[0],typeof(UserA));

    Assert.IsInstanceOfType(users[1],typeof(UserB));

}

3.2.4 Singleton实例

publicinterfaceIUser

{

}

 

publicclassDefaultUser: IUser

{

}

 

publicclassUserA: IUser

{

}

 

publicclassUserB: IUser

{

}

 

[TestMethod]

publicvoidTestCreateSingletonInstance()

{

    IUnityContainercontainer = newUnityContainer()

        .RegisterType<IUser, DefaultUser>(newContainerControlledLifetimeManager());

    IUseruserA = container.Resolve<IUser>();

    IUseruserB = container.Resolve<IUser>();

    IUseruserC = container.Resolve<IUser>();

    Assert.IsNotNull(userA);

    Assert.IsNotNull(userB);

    Assert.IsNotNull(userC);

    Assert.AreSame(userA, userB);

    Assert.AreSame(userB, userC);

 

    container.Dispose();

}

3.2.5 MethodInjection

publicclassObjectWithTwoProperties

{

    intmax;

    stringmessage;

    intcount;

 

    publicintMax

    {

       get{ returnmax; }

    }

 

    publicstringMessage

    {

       get{ returnmessage; }

    }

 

    publicintCount

    {

       get{ returncount; }

    }

 

    [InjectionMethod]

    publicvoidInjectInt(intmax)

    {

       this.max = max;

    }

 

    [InjectionMethod]

    publicvoidInjectString(stringmessage, intcount)

    {

       this.message = message;

       this.count = count;

    }

}

 

[TestMethod]

publicvoidTestMethodInjection()

{

    IUnityContainercontainer = newUnityContainer();

    container.RegisterType<ObjectWithTwoProperties>(

       newInjectionMethod("InjectInt", 30),

       newInjectionMethod("InjectString", "Hello", 15));

    ObjectWithTwoPropertiestarget = container.Resolve<ObjectWithTwoProperties>();

    Assert.IsNotNull(target);

    Assert.AreEqual<int>(30, target.Max);

    Assert.AreEqual<string>("Hello", target.Message);

    Assert.AreEqual<int>(15, target.Count);

}

3.2.6 ConstructorInjection

publicclassDepObj1

{

    publicstringValue;

}

 

publicclassDepObj2

{

    publicstringValue;

}

 

publicclassUserObj

{

    stringv1;

    stringv2;

 

    [InjectionConstructor]

    publicUserObj(DepObj1obj1, DepObj2obj2)

    {

        v1 = obj1.Value;

        v2 = obj2.Value;

    }

 

    publicstringV1

    {

       get{ returnv1; }

    }

 

    publicstringV2

    {

       get{ returnv2; }

    }

}

 

conststringV1 = "Hello";

conststringV2 = "World";

 

[TestMethod]

publicvoidTestConstructorInjection()

{

抱歉!评论已关闭.