0

これはTwitter からの質問でした。

インターフェイス モデルからアイテムを作成するためのパターンは何ですか? sitecoreService.Create<T,K>(T newItem, K parent)where is a インターフェイスを使用するにTは、クラスを追加して新しい項目を作成する必要があります。インターフェイスから直接作成する方法はありますか?

4

1 に答える 1

4

値を保存する前に値を書き込むインターフェイスの具体的なバージョンが必要なため、これは課題です。簡単な解決策は、次のインターフェイスを使用して、NSubstitute のようなモック フレームワークを使用することです。

    [SitecoreType(TemplateId = "{7FC4F278-ADDA-4683-944C-554D0913CB33}", AutoMap = true)]
    public interface StubInterfaceAutoMapped
    {
        Guid Id { get; set; }

        Language Language { get; set; }

        string Path { get; set; }

        int Version { get; set; }

        string Name { get; set; }

        string StringField { get; set; }
    }

次のテストを作成できます。

    [Test]
    public void Create_UsingInterface_CreatesANewItem()
    {
        //Assign
        string parentPath = "/sitecore/content/Tests/SitecoreService/Create";
        string childPath = "/sitecore/content/Tests/SitecoreService/Create/newChild";
        string fieldValue = Guid.NewGuid().ToString();

        var db = Sitecore.Configuration.Factory.GetDatabase("master");
        var context = Context.Create(Utilities.CreateStandardResolver());
        context.Load(new SitecoreAttributeConfigurationLoader("Glass.Mapper.Sc.Integration"));
        var service = new SitecoreService(db);

        using (new SecurityDisabler())
        {
            var parentItem = db.GetItem(parentPath);
            parentItem.DeleteChildren();
        }

        var parent = service.GetItem<StubClass>(parentPath);

        var child = Substitute.For<StubInterfaceAutoMapped>();
        child.Name = "newChild";
        child.StringField = fieldValue;

        //Act
        using (new SecurityDisabler())
        {
            service.Create(parent, child);
        }

        //Assert
        var newItem = db.GetItem(childPath);

        Assert.AreEqual(fieldValue, newItem["StringField"]);

        using (new SecurityDisabler())
        {
            newItem.Delete();
        }

        Assert.AreEqual(child.Name, newItem.Name);
        Assert.AreEqual(child.Id, newItem.ID.Guid);
    }

これは、 Glass.Mapper がマップされるタイプを解決する方法のために機能します。

    /// <summary>
    /// Gets the type configuration.
    /// </summary>
    /// <param name="obj">The obj.</param>
    /// <returns>AbstractTypeConfiguration.</returns>
    public AbstractTypeConfiguration GetTypeConfiguration(object obj)
    {
        var type = obj.GetType();
        var config = TypeConfigurations.ContainsKey(type) ? TypeConfigurations[type] : null;

        if (config != null) return config;

        //check base type encase of proxy
        config = TypeConfigurations.ContainsKey(type.BaseType) ? TypeConfigurations[type.BaseType] : null;

        if (config != null) return config;

        //check interfaces encase this is an interface proxy
        string name = type.Name;
        //ME - I added the OrderByDescending in response to issue 53
        // raised on the Glass.Sitecore.Mapper project. Longest name should be compared first
        // to get the most specific interface
        var interfaceType = type.GetInterfaces().OrderByDescending(x=>x.Name.Length).FirstOrDefault(x => name.Contains(x.Name));

        if (interfaceType != null)
            config = TypeConfigurations.ContainsKey(interfaceType) ? TypeConfigurations[interfaceType] : null;

        return config;
    }

直接一致する型が見つからない場合は、渡された型に関連付けられたインターフェイスに基づいて型の決定を開始し、名前に基づいて最初に見つかったものを使用することに注意してください。NSubstitute は Castle Dynamic Proxies も使用しているため、動作すると思われます。他のモッキング フレームワークでテストすることは興味深いでしょう。

于 2013-09-24T06:32:07.863 に答える