I have a task of creating XML messages from templates. Messages share the same header, but have different content. I used Fluent Recursive Generic Builder pattern (or 2, or SO questions on generic builders) to create/modify these messages.
public abstract class MessageBuilderBase<T> where T : IsoMessageBuilderBase<T>
{
protected XDocument _Message;
protected T _this;
public MessageBuilderBase(XDocument doc)
{
_Message = doc;
_this = (T)this;
}
public XDocument Build() => _Message;
public T SetTo(String toAddress)
{
// ... setting header field //
return _this;
}
}
public MessageType1Builder<T> : MessageBuilderBase<T> where T : MessageType1Builder<T>
{
public MessageType1Builder(XDocument message) : base(message) { }
public T SetMessageType1Property1(string value)
{
// set value //
return _this;
}
}
public MessageType2Builder<T> : MessageBuilderBase<T> where T : MessageType2Builder<T>
{
public MessageType2Builder(XDocument message) : base(message) { }
public T SetMessageType2Property1(string value)
{
// set value //
return _this;
}
}
I would like to split header and body in two different sections, so that I could write something like:
new MessageType1Builder(templateMessage).
Header.
SetTo(toValue).
Body.
SetMessageType1Property1(p1Value).
Build()
For that I tried to use approach described in Faceted Builder pattern, but I got stuck on the Header
and Body
property declarations with the errors like Cannot convert 'MessageBodyBuilder<T>' to 'T'
, or 'T' cannot be used as generic parameter 'T'
"Updated" code:
public abstract class MessageBuilderBase<T> where T : IsoMessageBuilderBase<T>
{
protected XDocument _Message;
protected T _this;
public MessageBuilderBase(XDocument doc)
{
_Message = doc;
_this = (T)this;
}
public T Header => MessageHeaderBuilder(_Message);
public MessageBodyBuilder<T> Body => MessageBodyBuilder(_Message)
public XDocument Build() => _Message;
}
public MessageHeaderBuilder<T> : MessageBuilderBase<T> where T : MessageHeaderBuilder<T>
{
public T SetTo(String toAddress)
{
// ... setting header field
return _this;
}
}
public MessageBodyBuilder<T> : MessageBuilderBase<T> where T : MessageHeaderBuilder<T>
{
// Common Methods
}
public MessageType1Builder<T> : MessageBodyBuilder<T> where T : MessageType1Builder<T>
{
public MessageType1Builder(XDocument message) : base(message) { }
public T SetMessageType1Property1(string value)
{
// set value
return _this;
}
}
public MessageType2Builder<T> : MessageBodyBuilder<T> where T : MessageType2Builder<T>
{
public MessageType2Builder(XDocument message) : base(message) { }
public T SetMessageType2Property1(string value)
{
// set value
return _this;
}
}
Can these two patterns be applied together? Am I missing something critical in my understanding of C# generics, and these two patterns?
Aucun commentaire:
Enregistrer un commentaire