Как я понял задачу: у вас есть две сущности, реализация которых неизвестна:
- подписываемый объект
- сервис генерации подписи
Объект ничего не знает, каким сервисом он будет подписан, а сервис не знает, какая структура у подписываемого объекта.
В этом случае логично ввести некую промежуточную сущность, в которую объект может себя сериализовать, а сервис будет знать, как её подписать. В простейшем случае это может быть массив, например, byte[]. Можно придумать более изощренный способ с потоковой генерацией подписи, чтобы не создавать промежуточный объект.
Может, я неправильно понял задачу, но вот, что у меня вышло.
Интерфейсы:
public interface ISignable
{
ISignature Signature { get; set; }
byte[] Serialize();
}
public interface ISignature
{
}
public interface ISignatureService
{
bool Validate(ISignable signable);
void Sign(ISignable signable);
}
Простейшая имплементация (в качестве подписи используется просто хеш-код):
class MyObject : ISignable
{
public ISignature Signature { get; set; }
public long Param1 { get; set; }
public string Param2 { get; set; }
public string InnerData { get; set; }
public byte[] Serialize()
{
return Encoding.UTF8.GetBytes(Param1 + Param2 + InnerData);
}
}
public class HashCodeSignatureService : ISignatureService
{
public void Sign(ISignable signable)
{
var signature = CalculateSignature(signable);
signable.Signature = signature;
}
public bool Validate(ISignable signable)
{
var s1 = CalculateSignature(signable);
var s2 = signable.Signature as SimpleHashCodeSignature;
return s1?.HashCode == s2?.HashCode;
}
private static SimpleHashCodeSignature CalculateSignature(ISignable signable)
{
var body = signable.Serialize();
var signature = new SimpleHashCodeSignature(body.Aggregate(0, (a, b) => a + b.GetHashCode()));
return signature;
}
}
public class SimpleHashCodeSignature : ISignature
{
public int HashCode { get; }
public SimpleHashCodeSignature(int hashCode)
{
HashCode = hashCode;
}
}
А так это можно использовать:
class Program
{
static void Main(string[] args)
{
var obj = new MyObject {Param1 = 1, Param2 = "asd", InnerData = "some data"};
var signatureService = new HashCodeSignatureService();
signatureService.Sign(obj);
// Passing the object across untrusted boundary
signatureService.Validate(obj);
}
}