14

MongoDB (C# ドライバーを使用) とDDDを使用するプロジェクトを開発しています。

タイプがインターフェースであるプロパティを持つクラス(集約)があります。別のクラスで、このインターフェイスを実装しました。このクラスには、タイプがインターフェースであり、別の実装されたクラスで設定される別のプロパティがあります。

以下のコードは、よりよく説明しています。

// Interfaces
public interface IUser {
    Guid Id { get; set;}
    IPartner Partner{ get; set; }
}

public interface IPartner {
    IPhone Mobile { get; set; }
}

public interface IPhone {
    string number { get; set; }
}

// Implemented Classes
public class User: IUser {
    [BsonId(IdGenerator = typeof(GuidGenerator))]
    public Guid Id { get; set; }

    [BsonIgnoreIfNull]
    public IPartner Partner { get; set; }
}

public struct Partner : IPartner {
    public IPhone Mobile { get; set; }
}

public struct Phone : IPhone {
    public string Number { get; set; }
}

メソッドを呼び出すと、次のMongoCollection<User>.Insert()2 つの例外がスローされます。

System.IO.FileFormatException: クラス .User の Partner プロパティの逆シリアル化中にエラーが発生しました: クラス .Partner の Phone プロパティの逆シリアル化中にエラーが発生しました: 値クラス .Mobile は逆シリアル化できません。---> System.IO.FileFormatException: クラス .Partner の Mobile プロパティの逆シリアル化中にエラーが発生しました: 値クラス .Phone を逆シリアル化できません。---> MongoDB.Bson.BsonSerializationException: 値クラス .Phone を逆シリアル化できません。

BsonClassMap.RegisterClassMap次に、インターネットを検索して、型をインターフェイスとして逆シリアル化する方法を見つけました。それを行うには、プロパティをキャストでマッピングする、カスタム BSON シリアライザーを使用する、または記述する必要があると思います。

これら 2 つの方法のどちらが優れているか、およびその実装方法を知る必要があります。

:プロジェクトには外部参照を含めることができないため、インターフェイスを変更しないソリューションが必要です。

4

4 に答える 4

14

さて、この答えを得ようとしたとき、私は多くの問題を発見しました。

まず第一に、MongoDB C# ドライバーには、この質問のコメントで Craig Wilson が述べたように、インターフェイスを逆シリアル化するときにいくつかの問題があり、問題のページで説明されています。

前に述べたように、この問題の安全な実装は、実際にはカスタム BSON シリアライザーまたはBsonClassMap.RegisterClassMap.

そのため、クラス マップを実装しましたが、問題は解決しませんでした。

この問題を楽しみにしていると、例外がドライバーの別の問題に関連してstructsいることがわかりました。

プロジェクトを初期状態 (クラス マップまたはカスタム シリアライザーなし) にロールバックし、構造体型をクラス型に変更したところ、うまくいきました。

再開すると、この例外エラーはインターフェイスの逆シリアル化ではなく、構造体の逆シリアル化に関連しています。


とにかく、これは本当の問題であり、最初の問題のように、2 番目の問題は改善というよりもバグと見なす必要があります。

問題は次のリンクにあります。

于 2013-01-28T19:13:41.733 に答える