2

Example: I have a countries catalog stored in another DB and I need to use it as a property in some ContentParts. I'm trying to make the connection without interfering much with Orchard wiring.

public class MoviePart : ContentPart<MoviePartRecord>
{
    public IEnumerable<CountryRecord> Countries
    {
        get
        {
            return Record.Countries.Select(r => r.CountryRecord);
        }
    }
}

The relation between CountryRecords and MovieParts will be on the Orchard DB, but the CountryRecord data is in another DB. I only need Read access, but I don't get which and how to override the Handler to use the other source.

Do I need to create a ContentHandler and override all methods, and create another StorageFilter that uses the new repository with the external source? And how would I inject the new repo into the handler?

public class CountryPartHandler : ContentHandler
{
    public CountryPartHandler(IRepository<CountryPartRecord> repository)
    {
        Filters.Add(StorageFilter.For(repository));
    }

    protected override void Loading(LoadContentContext context)
    {
        base.Loading(context);
    }
}

Update:

In this Using External Data with Orchard (around 25th min) video, he seems to be doing what I need with this code:

public ProductPartHandler(IRepository<ProductPartRecord> repository, Work<IProductService> productServiceWork)
    {
        Filters.Add(StorageFilter.For(repository));

        OnActivated<ProductPart>((context, part) => {
            part.ProductField.Loader(() => productServiceWork.Value.GetProduct(part.Id));
        });
    }

But in my code it can't find the "Loader" function, even though I have all the references from the video too, so maybe ProductField is a custom type?

Velair
  • 227
  • 3
  • 12

1 Answers1

2

So that is a lazy field on the part, something like this:

public class MyPart : ContentPart {
    internal readonly LazyField<CustomData> CustomDataField = new LazyField<CustomData>();

    public CustomData CustomData {
      get { return CustomDataField.Value; }
    }
}

public class CustomData {
    ...
}

public class MyPartHandler : ContentPartHandler {

   private ICustomService _customService;

   public MyPartHandler(ICustomService customService){
      _customService = customService;
      OnActivated<MyPart>(Initialize);
   }

   private void Initialize(ActivatedContentContext context, MyPart part){
         part.CustomDataField.Loader(() => {
             return _customService.Get(part.ContentItem.Id);
         });
   }
}

I don't know how you are loading your external data, whether via rest, wcf etc., but the logic can just be thrown into the custom service

Hazza
  • 6,441
  • 3
  • 24
  • 37
  • That's great, thanks. Is the OnActivated function enough for Orchard to handle the rest of the logic, or do I have to do the same for every event? (OnCreated, OnCreating...etc) – Velair Nov 27 '17 at 15:06
  • Just onactivated. This is called when the object hierarchy has been created, the lowest level event I believe. Oncreated is for when a content item has been created :) – Hazza Nov 27 '17 at 16:45