郁闷的PP

博客园 首页 新随笔 联系 订阅 管理

原文地址: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的类中注册。


Code

 

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

 

posted on 2008-09-04 14:57  郁闷的PP  阅读(4007)  评论(3编辑  收藏  举报