2011-09-16 15 views
8

Sử dụng công cụ bảo trì MongoDB trong joliver/EventStore gây ra lỗi Unknown discriminator value 'MyEvent'. Vấn đề này chỉ xảy ra khi tôi cố gắng để tải tất cả các sự kiện cho phát lại những sự kiện như this.storeEvent.Advanced.GetFrom(new DateTime(2010, 1,1))Giá trị phân biệt đối xử không xác định 'MyEvent'

Những vấn đề đang gây ra trong ExtensionsMethods.cs

public class MyClassEvent : IDomainEvent { ... } 

public static Commit ToCommit(this BsonDocument doc, IDocumentSerializer serializer) 
    { 
     if (doc == null) 
      return null; 

     var id = doc["_id"].AsBsonDocument; 
     var streamId = id["StreamId"].AsGuid; 
     var commitSequence = id["CommitSequence"].AsInt32; 

     var events = doc["Events"].AsBsonArray.Select(e => e.AsBsonDocument["Payload"].IsBsonDocument ? BsonSerializer.Deserialize<EventMessage>(e.AsBsonDocument["Payload"].AsBsonDocument) : serializer.Deserialize<EventMessage>(e.AsBsonDocument["Payload"].AsByteArray)).ToList(); 
     var streamRevision = doc["Events"].AsBsonArray.Last().AsBsonDocument["StreamRevision"].AsInt32; 
     return new Commit(
      streamId, 
      streamRevision, 
      doc["CommitId"].AsGuid, 
      commitSequence, 
      doc["CommitStamp"].AsDateTime, 
      BsonSerializer.Deserialize<Dictionary<string, object>>(doc["Headers"].AsBsonDocument), 
      events); 
    } 

cấu hình của tôi là như thế này:

Wireup.Init()     
      .UsingMongoPersistence(connectionName, new DocumentObjectSerializer()) 
      .UsingBsonSerialization()  
      .UsingAsynchronousDispatcher()         
      .PublishTo(this.container.Resolve<IPublishMessages>()) 
      .Build(); 

Nhưng đã thử gần như tất cả các loại tùy chọn serializer.

Trả lời

10

Cố gắng đăng ký các đối tượng của bạn (chính các thông báo sự kiện cũng như các đối tượng của tải trọng EventStore) bằng phương pháp BsonClassMap.RegisterClassMap. Dường như phần mở rộng mongo của EventStore xử lý các chuỗi tải trọng tốt, nhưng không phải là các đối tượng deserialized ... ít nhất là việc đăng ký phân loại là giải pháp trong trường hợp của tôi.

+2

Cảm ơn bạn. Khi tôi lưu các cam kết, trình điều khiển db mongo đăng ký các lớp riêng của mình, tuy nhiên khi trả lời (đọc thuần túy) ánh xạ không được thực hiện. – Jacee

+0

Cảm ơn, mặc dù tôi không thể thấy tại sao điều này là cần thiết – JacobE

13

Tôi cũng đã tham gia vào quá trình này. Zsolt's câu trả lời là một điểm khởi đầu tốt, nhưng tôi đã kết thúc giải quyết nó hơi khác nhau.

Lưu ý rằng tôi không chỉ nhận được điều này khi myEventStore.Advanced.GetFrom(...); myEventStore.OpenStream(...) cũng không thành công. Điều này có ý nghĩa, bởi vì cả hai phương pháp sử dụng cùng một IPersistentStream và serializer.

Tôi không gặp sự cố này khi lần đầu tiên tôi duy trì sự kiện trước khi truy xuất sự kiện cùng loại. Rõ ràng MongoDB tạo ra một ClassMap khi nó được yêu cầu serialize một loại cho lần đầu tiên.

Dù sao, với tôi giải pháp là tạo một bản đồ lớp cho tất cả các loại sự kiện của tôi khi khởi động ứng dụng. Giả sử tất cả các loại đang trong lắp ráp SimpleCQRS.Event và lấy được từ SimpleCQRS.Event, tôi làm điều đó như thế này:

var types = Assembly.GetAssembly(typeof(SimpleCQRS.Event)) 
        .GetTypes() 
        .Where(type => type.IsSubclassOf(typeof(SimpleCQRS.Event))); 
foreach (var t in types) 
    BsonClassMap.LookupClassMap(t); 

Đối với tôi này hoạt động tốt hơn so với sử dụng BsonClassMap.RegisterClassMap<TypeToMap> như Zsolt gợi ý, bởi vì đó đòi hỏi một tham số kiểu chung chung, có nghĩa bạn phải manually add each event type.

+0

+1 cũng làm việc cho tôi! – RobertMS

+0

Ý tưởng tương lai tuyệt vời, chỉ với một số bản in nhỏ/báo trước rằng a) tất cả các lớp con 'SimpleCQRS.Event' sẽ được thêm vào bừa bãi, và b) tất cả các lớp con đã biết phải nằm trong cùng một assembly. – StuartLC