Question

I don´t want anything of these to be editable at all. For the Collections it seems crystal clear to use ReadOnlyCollection (though I don´t know if it´s a good way of always creating a new ReadOnlyCollection from the Collection (is it costly?)).

public static class Lookups
{
    private static Collection<MyBusinessObject> businessObjects;
    // [...]

    public static ReadOnlyCollection<MyBusinessObjects> BusinessObjects
    {
        get
        {
            return new ReadOnlyCollection<MyBusinessObject>(businessObjects);
        }
    }
    // [...]
}

But more important: What do I do with items inside the collections? I want this test to pass any ideas?

    [TestMethod]
    public void Items_Should_Not_Be_Editable()
    {
        var businessObject = Lookups.BusinessObjects.First();

        businessObject.Id = 1337;

        Assert.AreNotEqual(1337, Lookups.BusinessObjects.First().Id);
    }
Was it helpful?

Solution

When using ReadonlyCollection you don't have to create a new instance every time. An alternative is to expose an IEnumerable as it is read only too. Readonlycollection offers stronger protection as can be seen here.

An instance of the ReadOnlyCollection generic class is always read-only. A collection that is read-only is simply a collection with a wrapper that prevents modifying the collection; therefore, if changes are made to the underlying collection, the read-only collection reflects those changes. See Collection for a modifiable version of this class.

[Test]
public void TestNameTest()
{
    var names = new List<string>() {"Johan", "Tkrause"};
    var readOnlyCollection = new ReadOnlyCollection<string>(names);
    names.Add("Lars");
    Assert.AreEqual(3,readOnlyCollection.Count);
}

In your case:

private List<IMyBusinessObjectType> _businessObjects= new List<IMyBusinessObjectType>();
private ReadOnlyCollection<IMyBusinessObjectType> _readOnlybusinessObjects;
public ReadOnlyCollection<IMyBusinessObjectType> BusinessObjects
{
    get
    {
        if(_readOnlybusinessObjects==null)
            _readOnlybusinessObjects=new ReadOnlyCollection<IMyBusinessObjectType>(_businessObjects);
        return _readOnlybusinessObjects;
    }
}
public interface IMyBusinessObjectType
{
    string Name { get; }
}

public class MyBusinessObjectType : IMyBusinessObjectType
{
    public string Name { get; set; }
}

As for the business objects they could have private setters or implement a read-only interface as suggested by Lars.

OTHER TIPS

You should inherit MyBusinessObject from an interface and expose that.

internal class MyBusinessObject : IMyBusinessObject {
    public string Id { get; set; }
}

public interface IMyBusinessObject {
    public string Id { get; }
}

And then expose this interface in the collection MyCollection.

Maybe do the same for the collection and dont expose the add, remove, etc methods.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top