tags:

views:

113

answers:

1

I have following code:

public class Header
{
    Line Lines { get { ...}}

    public ICryptographer GetCryptographer(FieldGroup group)
    {
        ...
    }
}

public class Line
{

    public Header Header { get; set; }
    public FieldGroup FieldGroup { get; set; }

    ICryptographer CryptoGrapher { get { return Header.GetCryptographer(FieldGroup); } }

    public decimal? Month1
    {
        get { return _month1; }
        set
        {
            if (_month1 != value)
                Month1_Enc = CryptoGrapher.Encrypt(_month1 = value);
        }
    }
    private decimal? _month1;

    protected byte[] Month1_Enc { get; set; }

    //The same repeated for Month2 to Month12
}

public interface ICryptographer
{
    byte[] Encrypt(decimal? value);
    decimal? DecryptDecimal(byte[] value);
}

public enum FieldGroup
{
   ...
}

Shortly properties Month1 to Month12 are of type decimal? that should be encrypted before they are saved in database. I have also few other classes that have encrypted properties. Every property code looks exactly the same as Month1 I showed here.

Ideally I would like to have something like this:

Encrypted<decimal?> Month1 { get; set;}

but this is impossible because each object may have different Cryptographer (symmetric key).

Is there a way to refactor it to avoid such repeatable code?
Should I care about such repetition ?

A: 

So for each Encrypted you need a reference to the parent, I'm I correct?

So my first attempt would be trying get a reference to the parent into each usage of Encrypted first. I think lightweight interfaces are good for this kind of job:

public interface IHasEncryptedProperties
{
    string GetKey();
}

And then implement them on classes than need encrypted properties

public class Line : IHasEncryptedProperties
{
    public string GetKey() { /* return instance-specific key; */ }
}

Then on Encrypted you then requires that a parent instance be passed in.

public class Encrypted<T>
{
    private IHasEncryptedProperties _parent;

    public Encrypted(IHasEncryptedProperties parent)
    {
        _parent = parent;
    }

    public T Value
    {
        get
        {
            var encryptor = GetEncryptor(_parent.GetKey());
            // encrypt and return the value
        }
    }
}

..

Hope this helps. If it doesn't, please leave a comment.

chakrit
I thought about such way, but this will require to set parent if I want to set Month1 with new value. I can do it in two places 1) In code that is using Line instance which is worse beacuse I must remember about it in every place. 2) In Month1 setter method which is similiar amount of code I have right now.
SeeR
@SeeR You can overloads conversion operator from T to Encrypted<T> for the property setters part, but I'm not sure. Will get back to it and update this post when I have time.
chakrit
In conversion operators I don't have information about parent (unless I use some static fields - which I can't in this case)
SeeR
@SeeR Oh.. I understand your problem now... let's see what I can do...
chakrit