翻譯:Autofac.Module 介紹(Orchard)


雖然 Autofac 的確不是Orchard的公共API的一部分,它派上用場,當你需要自定義你的一些類的創建和管理的autofac,當你需要定制你的一些類是由Autofac創建和管理。

一般而言,當您編寫自己的注射類,您將采取下列步驟:

  • 1、定義一個接口,來源於IDependency;
  • 2、定義一個類,實現接口;

然而,在某些情況下,你可能想要注入具體的類直接進入你的構造函數,而不是一個接口。一個例子是當你在實現命令模式時,你通常會有多個類,最終實現一些ICommand接口,接下來,考慮使用一個控制器,依賴於一些命令,例如:SaveCustomerCommand。一個解決方案是為每個命令創建一個特定的接口。這將是完美的(甚至這些命令對於單元測試也是完美的)。但是我想由於某種原因你不想寫這些接口。但是你怎么能注入一個UpdateCustomerCommand或SaveCustomerCommand 呢?

為了這樣做,我們寫一個類繼承自Autofac.Module並且重載它的Load方法,Load方法接受一個類型為ContainerBuilder的參數,這就是所有我們需要注冊新的類型。

讓我們看一個例子:

首先,讓我們定義一個ICommand接口和兩個實現類:SaveCustomerCommand和CreateOrderCommand:

Commands/ICommand.cs:

public interface ICommand {
     void Execute();
}

Commands/SaveCustomerCommand.cs:

public class SaveCustomerCommand : ICommand {
        private readonly ICommerceServices _services;
 
        // Commands support DI just like any other class
        public SaveCustomerCommand(ICommerceServices services) {
            _services = services;
        }
 
        public void Execute() {
            // perform some action here, e.g. create a new customer or update an existing one
        }
}

 Commands/CreateOrderCommand.cs:

public class CreateOrderCommand : ICommand
    {
        private readonly ICommerceServices _services;
 
        // Commands support DI just like any other class
        public CreateOrderCommand(ICommerceServices services)
        {
            _services = services;
        }
 
        public void Execute()
        {
            // perform some action here, e.g. create a new order
        }
    }

這個ICommerceService接口只是一個接口示例它沒有任何成員:

Services/ICommerceServices.cs:

public interface ICommerceServices {}

接下來,我們將定義兩個控制器,一個控制器需要依賴SaveCustomerCommand而其他需要依賴CreateOrderCommand。

Controllers/CustomerController.cs:

public class CustomerController : Controller {
        private readonly SaveCustomerCommand _saveCommand;
 
        // Inject a SaveCustomerCommand
        public CustomerController(SaveCustomerCommand saveCommand) {
            _saveCommand = saveCommand;
        }
 
        public ActionResult CreateCustomer() {
            _saveCommand.Execute();
            return Content("Customer created");
        }
    }

 

Controllers/OrderController.cs:

using System.Web.Mvc;
using Orchard.Docs.Misc.Commands;
 
namespace Orchard.Docs.Misc.Controllers {
    public class OrderController : Controller {
        private readonly CreateOrderCommand _createOrderCommand;
 
        // Inject a CreateOrderCommand
        public OrderController(CreateOrderCommand createOrderCommand) {
            _createOrderCommand = createOrderCommand;
        }
 
        public ActionResult CreateOrder() {
            _createOrderCommand.Execute();
            return Content("Order created");
        }
    }
}

 

現在,為了讓這個工作,我們需要告訴Autofac如何給我們這些命令類型。創建另一個類,它來繼承自Autofac.Module(注意:需要添加 Autofac程序集的引用。)

ModuleBuilders/CommandsModule.cs:

using Autofac;
using Autofac.Features.ResolveAnything;
 
public class CommandsModule : Module {
    protected override void Load(ContainerBuilder builder)
    {
        // Configure Autofac to create a new instance of any type that implements ICommand when such type is requested
        builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(t => t.IsAssignableTo<ICommand>()));
    }
}

 

基本上,我們為注冊了一個類型:“AnyConcreteTypeNotAlreadyRegisteredSource”,傳遞一個謂詞的類型注冊。我們通知他注冊所有的類型,通過利用Autofac的擴展方法IsAssignableTo < T >實現ICommand。

效果:每當我們請求一個實現了ICommand類型,Autofac將為我們提供該類型的示例。

 

原文地址:http://skywalkersoftwaredevelopment.net/orchard-development/api/autofac-module


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM