构建Orchard模块 - 告诉Autofac使用不同的实现

时间:2013-11-04 03:38:34

标签: orchardcms autofac

当我暴露here时,我希望能够在没有Orchard为我构建查询的情况下自由查询索引。

我构建了一个模块,并插入了一个SearchController的副本,添加了一个新的路由...... 要覆盖有关查询的默认Orchard行为,我必须创建新的实现:ISearchService,IIndexManager,ISearchBuilder,IIndexProvider。 它们的默认实现有一些小修改,但它们是必需的。

按预期工作,但它当前也会覆盖默认搜索。 这是因为我使用了相同的接口,autofac采用了我的实现。

我希望能够保持默认实现不变(在url / Search上),并在url上添加我的实现(例如/ LuceneSearch)

我想我必须通过创建一个继承autofac Module类的类来告诉Autofac仅将我的实现用于我的控制器。 这是我的问题:我不知道如何告诉Autofac默认使用Orchard Implementation,而且只是为了我的控制器,使用我的实现....

另一种可能性是创建新的界面,但在我看来并不是真的很漂亮......

有人能帮助我吗? :)

3 个答案:

答案 0 :(得分:1)

Metadata功能将在此为您提供帮助。此外,您必须使用PreserveExistingDefaults()修饰符注册您的实现,以默认保留orchard的实现。

<强>更新

Orchard从Autofac的IModule实现和Orchard的IDependency中注册所有依赖项。所有魔法都发生在Orchard的ShellContainerFactory类中。由于ISearchService继承自IDependency,因此Orchard会注册您的实现,并覆盖默认的实现 你有两种方法:

  1. 介绍自己的空接口IMySearchService,它继承自ISearchService。在您需要实施的代码中实现并使用它。 Orchard将处理您的所有注册。
  2. Orchard在ShellContainerFactory.RegisterType方法中使用“Feature”元数据注册所有IDependency实现。您可以在代码中阅读此元数据并选择您的实现(请参阅上面的wiki链接)。要素类包含有关模块的所有必要信息。
  3. 希望这会对你有所帮助。

答案 1 :(得分:1)

一个更简单的方法,不涉及Autofac的复杂性,就是在url“/ LuceneSearch”的控制器/驱动程序中使用IEnumerable<IInterface>变量来保存IInterface的所有实现并选择要使用哪个

例如,为了使用IIndexManager的实现,您可以在控制器或驱动程序中添加以下内容

public class MyCustomPartDriver : ContentPartDriver<MyCustomPart> {
    private readonly IEnumerable<IIndexManager> _indexManagers;

    public MyCustomPartDriver(IEnumerable<IIndexManager> indexManagers) {
        _indexManagers = indexManager;
    }

    protected override DriverResult Display(MyCustomPart part, string displayType, dynamic shapeHelper) {
        //Use your implementation of IIndexManager
        var indexManager = _indexManagers.First(im => im is MyCustomIndexManager);

        //Get the ISearchBuilder from your implementation of IIndexManager
        var searchBuilder = indexManager.HasIndexProvider() ? indexManager.GetSearchIndexProvider().CreateSearchBuilder("Search") : new NullSearchBuilder();

        //perform search on the indexing engine
        var contentItemIds = searchBuilder.
            .WithField("type", "MyCustomType").Mandatory().ExactMatch()
            .Parse("mycustompart-keyword", part.Keyword).Mandatory()
            .Search()
            .Select(h => h.ContentItemId)
            .ToList();

        //do stuff with the results returned and return a DriverResult using the ContentShape method. Well, you know the drill.
    }
}

答案 2 :(得分:0)

如果您不希望autofac默认解析您自己的实现,那么请不要实现公共接口。