[翻译]StructureMap 指南 – .NET中的依赖注入和控制反转

原文地址:http://www.pnpguidance.net/Post/StructureMapTutorialDependencyInjectionIoCNET.aspx

StuctureMap 是一种.NET下的依赖注入框架,希望2.5版早点发布(目前最新是2.4.9)。这篇指南可以帮助您入门。

StructureMap依赖注入基础

在大多数ASP.NET WEB应用程序、智能客户端程序、WPF程序中,你都可以通过提供接口,创建可重用的服务。如:你定义一个接口叫ILogger,这个接口声明一组契约,为你的程序记录日志,并且你做了不同的、可重用的实现这个接口的类,如:类DatabaseLogger,把日志记录到数据库中。

当有一个对ILogger请求的时候,我们可以叫StructureMap注入返回一个DatabaseLogger的实例:

StructureMapConfiguration
    .ForRequestedType
< ILogger > ()
    .TheDefaultIsConcreteType
< DatabaseLogger > ()
    .CacheBy(InstanceScope.Singleton);

我们可以使用StructureMapConfiguration类创建一个Singleton模式的DatabaseLogger,也就是在整个应用程序中有且仅有一个实例的DatabaseLogger

你可以使用StructureMapObjectFactory类取出这个ILogger的实例:

ILogger logger  =  ObjectFactory.GetInstance < ILogger > ();

StructureMap会返回一个DatabaseLogger的实例,之前我们已经做好了DatabaseLoggerILogger的映射。

然后把这些代码放到一个最简单的控制台应用程序中:


namespace  StructureMapTutorials
{
    
class  Program
    {
        
static   void  Main( string [] args)
        {
            StructureMapConfiguration
                .ForRequestedType
< ILogger > ()
                .TheDefaultIsConcreteType
< DatabaseLogger > ()
                .CacheBy(InstanceScope.Singleton);
 
            ILogger logger 
=  ObjectFactory.GetInstance < ILogger > ();
        }

    }

 

     public interface ILogger {}  

     public class DatabaseLogger : ILogger {}

}

 更精彩的是: StructureMap会自动在对象中注入所依赖的对象实例。比如我们的程序里还有个CustomerDataSource类,也需要ILogger服务:

public   interface  ICustomerDataSource { }

public   class  CustomerDataSource : ICustomerDataSource
{
    
private   readonly  ILogger _logger;

    
public  CustomerDataSource(ILogger logger)
    {
        _logger 
=  logger;
    }
}

我们把ICustomerDataSource接口的具体实现CustomerDataSource类也注册到StructureMap中,就像刚才的ILogger服务一样:

StructureMapConfiguration
    .ForRequestedType
< ICustomerDataSource > ()
    .TheDefaultIsConcreteType
< CustomerDataSource > ()
    .CacheBy(InstanceScope.Singleton);

and then we can ask for an instance of ICustomerDataSource from StructureMap's ObjectFactory Class, which automatically injects the propery ILogger Service into the CustomerDataSource Class' Constructor for us:

然后,我们向StructureMapObjectFactory类请求一个ICustomerDataSource的实例,它会自动把ILogger属性注入服务到CustomerDataSource类的构造方法中:

ICustomerDataSource dataSource  =
    ObjectFactory.GetInstance
< ICustomerDataSource > ();

你可以通过下面的控制台程序看到StructureMap是怎样运行的:

using  StructureMap;
using  StructureMap.Attributes;

namespace  StructureMapTutorials
{
    
class  Program
    {
        
static   void  Main( string [] args)
        {
            StructureMapConfiguration
                .ForRequestedType
< ILogger > ()
                .TheDefaultIsConcreteType
< DatabaseLogger > ()
                .CacheBy(InstanceScope.Singleton);

            StructureMapConfiguration
                .ForRequestedType
< ICustomerDataSource > ()
                .TheDefaultIsConcreteType
< CustomerDataSource > ()
                .CacheBy(InstanceScope.Singleton);

            ICustomerDataSource dataSource 
=
                ObjectFactory.GetInstance
< ICustomerDataSource > ();
        }
    }

    
public   interface  ILogger { }

    
public   class  DatabaseLogger : ILogger { }

    
public   interface  ICustomerDataSource { }

    
public   class  CustomerDataSource : ICustomerDataSource
    {
        
private   readonly  ILogger _logger;

        
public  CustomerDataSource(ILogger logger)
        {
            _logger 
=  logger;
        }
    }
}

 

StructureMap注册表

通常依赖注入和控制反转工具都有以组关系注册的方式。StructureMap注册表的概念。我们可以改变上面的代码,把ILoggerICustomerDataSource放到一组叫ServiceRegistry的类中注册。


ContractedBlock.gif ExpandedBlockStart.gif Code
using StructureMap;
using StructureMap.Attributes;
using StructureMap.Configuration.DSL;

namespace StructureMapTutorials
{
    
class Program
    {
        
static void Main(string[] args)
        {
            StructureMapConfiguration
                .AddRegistry(
new ServiceRegistry());

            ICustomerDataSource dataSource 
=
                ObjectFactory.GetInstance
<ICustomerDataSource>();
        }
    }

    
public class ServiceRegistry : Registry
    {
        
protected override void configure()
        {

                ForRequestedType
<ILogger>()
                .TheDefaultIsConcreteType
<DatabaseLogger>()
                .CacheBy(InstanceScope.Singleton);

                ForRequestedType
<ICustomerDataSource>()
                .TheDefaultIsConcreteType
<CustomerDataSource>()
                .CacheBy(InstanceScope.Singleton);
        }
    }

    
public interface ILogger { }

    
public class DatabaseLogger : ILogger { }

    
public interface ICustomerDataSource { }

    
public class CustomerDataSource : ICustomerDataSource
    {
        
private readonly ILogger _logger;

        
public CustomerDataSource(ILogger logger)
        {
            _logger 
= logger;
        }
    }
}

 

StructureMap PluginFamilyPluggable特性

如果你愿意使用特性让StructureMap扫描不同的程序集并自动注册不同的类型到你的程序,你可以使用PluginFamilyPluggable特性:

using  StructureMap;
using  StructureMap.Attributes;
using  StructureMap.Configuration.DSL;

namespace  StructureMapTutorials
{
    
class  Program
    {
        
static   void  Main( string [] args)
        {
            StructureMapConfiguration
                .ScanAssemblies()
                .IncludeTheCallingAssembly();

            ICustomerDataSource dataSource 
=
                ObjectFactory.GetInstance
< ICustomerDataSource > ();
        }
    }

    [PluginFamily(
" Database " , IsSingleton  =   true )]
    
public   interface  ILogger { }
 

    [Pluggable(
" Database " )]
    
public   class  DatabaseLogger : ILogger { }

 
    [PluginFamily(
" CustomerDataSource " , IsSingleton  =   true )]
    
public   interface  ICustomerDataSource { }


    [Pluggable(
" CustomerDataSource " )]
    
public   class  CustomerDataSource : ICustomerDataSource
    {
        
private   readonly  ILogger _logger;

        
public  CustomerDataSource(ILogger logger)

        {
            _logger 
=  logger;
        }
    }
}

 

结语

这篇文章介绍了些在.NET中使用StructureMap框架依赖注入和控制反转的基础知识。

你也可以试试这些工具:Autofac, Castle Windsor, Ninject, SpringFramework.net, Unity

希望对您有所帮助,David Hayden

 

转载于:https://www.cnblogs.com/darkdawn/archive/2008/09/04/1284018.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值