在Orchard内使用非果园服务类

时间:2011-12-06 16:42:41

标签: dependency-injection autofac orchardcms

我们最近开发了一个在内部使用MVC3应用程序的类库。 MVC3应用程序使用Autofac在运行时为控制器注入所需的服务类。该库使用自己的一组表进行数据存储,这些表可能与主机应用程序位于同一数据库中,也可能不存在。

这些类遵循依赖注入模式,例如看起来像这样(是的,你之前已经看过它一百万次了)......

public class PackageService : ServiceBase, IPackageService
{
    private readonly IRepository _db;
    private readonly IClientService _clientSvc;

    public PackageService(IRepository db, IClientService clientService)
    {
        _db = db;
        _clientSvc = clientService;
    }

    public ServiceResult<IEnumerable<Package>> FindPackagesBy(string searchTerm, out int totalRecords, int pageSize, int pageIndex)
    {
        //...
    }

    public ServiceResult<Package> GetPackage(string packageRef)
    {
        //...
    }
}

我们希望在Orchard CMS中运行的模块中使用这些类。从我在how orchard works上看到的内容看来,我需要用IDependency接口来装饰我打算在Orchard中使用的每个类 - 这看起来不是一个好主意,因为这会创建一个对orchard本身的依赖。我们的类管理自己的事务/工作单元,因此不需要由orchards自己的事务机制来管理。这可能吗?或者我们是否正在面对我们现有库的Orchard特定实现?

很高兴听到任何已经通过此事的人。

2 个答案:

答案 0 :(得分:2)

你需要依赖Orchard并“实施”IDependency以便让他们注入AFAIK。但这不是一个失败的主张,对我来说听起来并不像让Orchard特定的版本与你描述的那样有多大的作用,特别是如果你想把数据移到Orchard。

答案 1 :(得分:2)

自己想出来......

在使用“外部库”的模块中,您创建一个Autofac文件夹,并添加一个继承自Autofac模块的类并在其中添加绑定(这是在Autofac中设置绑定的标准过程) - Orchard将在运行时发现这个并向模块控制器注入所需的依赖项。

但是,默认情况下,对外部库的调用包含在请求事务中,因为这是orchard的工作方式。因为我的库通过EF4调用SQL Server,我得到一个例外'MSDTC不可用'。您需要明确声明您不希望这些操作包含在事务中,因此您的控制器最终看起来像这样......

[Themed]
public class HomeController : Controller
{
    /* this service is from the external library, 
    which calls its own database */
    private readonly IPackageService _packageSvc;

    /* this dependency is injected, based upon the bindings
    i specified within the Autofac folder at module level */
    public HomeController(IPackageService packageService)
    {
        _packageSvc = packageService;
    }

    public ActionResult Index()
    {
        /* wrap the external lib call so it avoids inclusion
        within the orchard request transaction */
        using (new TransactionScope(TransactionScopeOption.Suppress))
        {
            var package = _packageSvc.GetPackage();
            var model = new HomePageModel()
            {
                Package = package
            };
            return View("ShowPackage", model);
        }

    }
}