Disclaimer: This is based on a beta version of Episerver.Forms, so anything can change in the future. When stuff breaks after updating, you're going to have to deal with that yourself. However, I'm bravely guessing the concept will live on in some form, since this gives developers a way to easily enrich the forms quite a bit.

If you have tested the new Episerver.Forms, you might have noticed the Feed-property with it's default value "Use manual input" when editing Selection or Single/Multiple Choice type input type elements. 

In the config file that follows the package, there's an example that shows how you can add an RSS feed to your available data sources when displaying the input element to the end user.

However, there is another way. You can control the feeds through code; for example adding data from web services, files a custom database or other data source. You'll need three things:

1. The data feed itself

For this, you need to implement the EPiServer.Forms.Core.ExternalFeed.IFeed interface. I've provided an example below.

public class CustomFeed : IFeed
{
    public string EditViewFriendlyTitle { get { return "Friendly title"; } }
    public bool AvailableInEditView { get { return true; } }

    public IEnumerable<IFeedItem> LoadItems()
    {
        var selectItems = new List<IFeedItem>();

        selectItems.Add(new FeedItem { Key = "Foo", Value = "1" });
        selectItems.Add(new FeedItem { Key = "Bar", Value = "2" });
        selectItems.Add(new FeedItem { Key = "Baz", Value = "3" });

        return selectItems;
    }

    // Required for this to work. Seems to be used to identify the feed on the saved form. 
    // If this changes, your dropdown loses it's possible values.
    public string ID
    {
        get { return "9BC5243C-AC09-4E67-AAAB-78D111F57AF8"; }
        set { }
    }

    public string Description
    {
        get { return "My custom data source"; }
        set { }
    }

    public Type ProviderType
    {
        get { return typeof(CustomFeedProvider); }
        set { }
    }

    public string Url { get; set; }
    public string ProviderKey { get; set; }
    public string ProviderSecret { get; set; }
    public string KeyXPath { get; set; }
    public string ValueXPath { get; set; }
    public int CacheTimeout { get; set; }
    public string ExtraConfiguration { get; set; }
    public IFeedProvider AssociatedProvider { get; set; }
}

This provides the actual elements for the end user, and this is where you'd hit the web service, database or file of choice.

2. A custom feed provider

As you might have noticed, my CustomFeed's ProviderType property returns the CustomFeedProvider type. So you'll need to implement this, which is very simple in it's most basic form.

public class CustomFeedProvider : IFeedProvider
{
    public IEnumerable<IFeedItem> LoadItems(IFeed feedToLoad)
    {
        return feedToLoad.LoadItems();
    }
}

As you can see, this provider is completely unaware of the feed itself, and could be reused for other feeds that doesn't need any output tweaking.

3. An IExternalSystemFieldMapping implementation

When Episerver looks for possible sources of data for these lists, it looks for implementations of the IExternalSystemFieldMapping interface. So you'll have to provide this too. For example, like this:

public class CustomFeedFieldMapping : IExternalSystemFieldMapping
{
    public Guid Guid
    {
        get { return Guid.Parse("107FF759-53C3-48CD-9A96-0CE0C1B82235"); }
    }

    public string Code { get { return "Code"; } }

    public IFeed FeedForMapping
    {
        get { return new CustomFeed(); }
    }
}

This interface seems to be made for mapping up your form fields against external systems (I'm guessing for when using the Web hooks or other integration points). However, it currently seems to be the only way to get your own feeds into the system.

4. Done!

And that was it! You should now have a new option when editing your form element.

Some thoughts...

For what it's worth - if any Episerver-developers read this: I like the concept, but it seems to require too much. Just to provide a simple data source for my dropdowns or multi choice input elements, an implementation of IFeed should be enough. And this interface shouldn't have to carry more than a name or language key and a GetItems()-style method. The rest could be optional for those special use cases when it's needed.