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

Orchardcms 构建Orchard模块-告诉Autofac使用不同的实现,orchardcms,autofac,Orchardcms,Autofac,正如我所揭示的,我希望能够自由地查询索引,而不必为我构建查询 我构建了一个模块,插入了SearchController的副本,添加了一个新的路由。。。 为了覆盖与查询相关的默认Orchard行为,我必须创建新的实现:ISearchService、IIndexManager、ISearchBuilder、IIndexProvider。 它们的默认实现有一些小的修改,但它们是必需的 这与预期的一样,但它目前也覆盖了默认搜索。 这是因为我使用了相同的接口,autofac采用了我的实现 我希望能够保持默

正如我所揭示的,我希望能够自由地查询索引,而不必为我构建查询

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

这与预期的一样,但它目前也覆盖了默认搜索。 这是因为我使用了相同的接口,autofac采用了我的实现

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

我想我必须通过创建一个继承Autofac模块类的类来告诉Autofac仅为我的控制器使用我的实现。 这是我的问题:我不知道如何告诉Autofac在默认情况下使用Orchard实现,而对于我的控制器,使用我的实现

另一种可能是创建新的接口,但在我看来,它并不是很漂亮

有人能帮我吗?:)

功能将在这里帮助您。此外,您还必须使用modifier注册您的实现,以在默认情况下保留orchard的实现

更新:

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

  • 引入您自己的空接口IMySearchService,它继承自ISearchService。在需要实现的代码中实现并使用它。Orchard将处理您的所有注册
  • Orchard使用ShellContainerFactory.RegisterType方法中的“Feature”元数据注册所有IDependency实现。您可以在代码中读取此元数据并选择实现(请参见上面的wiki链接)。要素类包含有关模块的所有必要信息

  • 希望这能对您有所帮助。

    如果您不想让autofac在默认情况下解析您自己的实现,那么就不要实现公共接口。

    一个不涉及autofac复杂性的更简单的方法是在控制器/驱动程序的url“/LuceneSearch”中使用一个
    IEnumerable
    变量保存
    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.
        }
    }
    
    公共类MyCustomPartDriver:ContentPartDriver{
    私有只读IEnumerable _IndexManager;
    公共MyCustomPartDriver(IEnumerable IndexManager){
    _indexManager=indexManager;
    }
    受保护的覆盖驱动程序结果显示(MyCustomPart部件、字符串显示类型、动态形状帮助){
    //使用IIndexManager的实现
    var indexManager=_indexManagers.First(im=>im是MyCustomIndexManager);
    //从IIndexManager的实现中获取ISearchBuilder
    var searchBuilder=indexManager.HasIndexProvider()?indexManager.GetSearchIndexProvider()。CreateSearchBuilder(“搜索”):新的NullSearchBuilder();
    //在索引引擎上执行搜索
    var contentItemIds=searchBuilder。
    .WithField(“类型”、“MyCustomType”).Mandatory().ExactMatch()
    .Parse(“mycustompart关键字”,part.keyword).Mandatory()
    .Search()
    .Select(h=>h.ContentItemId)
    .ToList();
    //使用ContentShape方法处理返回的结果并返回一个DriverResult。好吧,你知道这个练习。
    }
    }
    
    使用PreserveExistingDefaults()不起作用:它仍然使用我的实现。我想这是因为注册/接线是由Orchard自动执行的…@Sylvainerverdy谢谢你指点我,我更新了答案,希望能有所帮助。好的,我会这么做。但我认为定义同一个接口(使用另一个名称)有点难看,因为我不能简单地告诉Autofac我想要的实现。