This is such a simple and common scenario I wonder how did I managed until now and why I have problems now.
I have this object (part of the Infrastructure assembly)
public class Queue {}
public class QueueItem
{
public QueueItem(int blogId,string name,Type command,object data)
{
if (name == null) throw new ArgumentNullException("name");
if (command == null) throw new ArgumentNullException("command");
BlogId = blogId;
CommandType = command;
ParamValue = data;
CommandName = name;
AddedOn = DateTime.UtcNow;
}
public Guid Id { get; internal set; }
public int BlogId { get; private set; }
public string CommandName { get; set; }
public Type CommandType { get; private set; }
public object ParamValue { get; private set; }
public DateTime AddedOn { get; private set; }
public DateTime? ExecutedOn { get; private set; }
public void ExecuteIn(ILifetimeScope ioc)
{
throw new NotImplementedException();
}
}
This will be created in another assembly like this
var qi = new QueueItem(1,"myname",typeof(MyCommand),null);
Nothing unusal here. However, this object will be sent t oa repository where it will be persisted.The Queue object will ask the repository for items. The repository should re-create QueueItem objects.
However, as you see, the QueueItem properties are invariable, the AddedOn property should be set only once when the item is created. The Id property will be set by the Queue object (this is not important).
The question is how should I recreate the QueueItem in the repository? I can have another constructor which will require every value for ALL the properties, but I don't want that constructor available for the assembly that will create the queue item initially. The repository is part of a different assembly so internal won't work.
I thought about providing a factory method
class QueueItem
{
/* ..rest of definitions.. */
public static QueueItem Restore(/* list of params*/){}
}
which at least clears the intent, but I don't know why I don't like this approach. I could also enforce the item creation only by the Queue , but that means to pass the Queue as a dependency to the repo which again isn't something I'd like. To have a specific factory object for this, also seems way overkill.
Basically my question is: what is the optimum way to recreate an object in the repository, without exposing that specific creational functionality to another consumer object.
Update
It's important to note that by repository I mean the pattern itself as an abstraction, not a wrapper over an ORM. It doesn't matter how or where the domain objects are persisted. It matters how can be re-created by the repository. Another important thing is that my domain model is different from the persistence model. I do use a RDBMS but I think this is just an implementation detail which should not bear any importance, since I'm looking for way that doesn't depend on a specific storage access.
While this is a specific scenario, it can applied to basically every object that will be restored by the repo.
Update2
Ok I don't know how I could forget about AutoMapper. I was under the wrong impression it can't map private fields/setter but it can, and I think this is the best solution.
In fact I can say the optimum solutions (IMO) are in order:
Directly deserializing, if available.
Automap.
Factory method on the domain object itself.
The first two don't require the object to do anyting in particular, while the third requires the object to provide functionality for that case (a way to enter valid state data). It has clear intent but it pretty much does a mapper job.
Answer Updated
To answer myself, in this case the optimum way is to use a factory method. Initially I opted for the Automapper but I found myself using the factory method more often. Automapper can be useful sometimes but in quite a lot of cases it's not enough.
An ORM framework would take care of that for you. You just have to tell it to rehydrate an object and a regular instance of the domain class will be served to you (sometimes you only have to declare properties as virtual or protected, in NHibernate for instance). The reason is because under the hood, they usually operate on proxy objects derived from your base classes, allowing you to keep these base classes intact.
If you want to implement your own persistence layer though, it's a whole nother story. Rehydrating an object from the database without breaking the scope constraints originally defined in the object is likely to involve reflection. You also have to think about a lot of side concerns : if your object has a reference to another object, you must rehydrate that one before, etc.
You can have a look at that tutorial : Build Your Own dataAccess Layer although I wouldn't recommend reinventing the wheel in most cases.
You talked about a factory method on the object itself. But DDD states that entities should be created by a factory. So you should have a QueueItemFactory that can create new QueueItems and restore existing QueueItems.
Ok I don't know how I could forget about AutoMapper.
I wish I could forget about AutoMapper. Just looking at the hideous API gives me shivers down my spine.
Related
I had seen some books(e.g programming entity framework code first Julia Lerman) define their domain classes (POCO) with no initialization of the navigation properties like:
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public virtual ICollection<Address> Address { get; set; }
public virtual License License { get; set; }
}
some other books or tools (e.g Entity Framework Power Tools) when generates POCOs initializes the navigation properties of the the class, like:
public class User
{
public User()
{
this.Addresses = new IList<Address>();
this.License = new License();
}
public int Id { get; set; }
public string UserName { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
public virtual License License { get; set; }
}
Q1: Which one is better? why? Pros and Cons?
Edit:
public class License
{
public License()
{
this.User = new User();
}
public int Id { get; set; }
public string Key { get; set; }
public DateTime Expirtion { get; set; }
public virtual User User { get; set; }
}
Q2: In second approach there would be stack overflow if the `License` class has a reference to `User` class too. It means we should have one-way reference.(?) How we should decide which one of the navigation properties should be removed?
Collections: It doesn't matter.
There is a distinct difference between collections and references as navigation properties. A reference is an entity. A collections contains entities. This means that initializing a collection is meaningless in terms of business logic: it does not define an association between entities. Setting a reference does.
So it's purely a matter of preference whether or not, or how, you initialize embedded lists.
As for the "how", some people prefer lazy initialization:
private ICollection<Address> _addresses;
public virtual ICollection<Address> Addresses
{
get { return this._addresses ?? (this._addresses = new HashSet<Address>());
}
It prevents null reference exceptions, so it facilitates unit testing and manipulating the collection, but it also prevents unnecessary initialization. The latter may make a difference when a class has relatively many collections. The downside is that it takes relatively much plumbing, esp. when compared to auto properties without initialization. Also, the advent of the null-propagation operator in C# has made it less urgent to initialize collection properties.
...unless explicit loading is applied
The only thing is that initializing collections makes it hard to check whether or not a collection was loaded by Entity Framework. If a collection is initialized, a statement like...
var users = context.Users.ToList();
...will create User objects having empty, not-null Addresses collections (lazy loading aside). Checking whether the collection is loaded requires code like...
var user = users.First();
var isLoaded = context.Entry(user).Collection(c => c.Addresses).IsLoaded;
If the collection is not initialized a simple null check will do. So when selective explicit loading is an important part of your coding practice, i.e. ...
if (/*check collection isn't loaded*/)
context.Entry(user).Collection(c => c.Addresses).Load();
...it may be more convenient not to initialize collection properties.
Reference properties: Don't
Reference properties are entities, so assigning an empty object to them is meaningful.
Worse, if you initiate them in the constructor, EF won't overwrite them when materializing your object or by lazy loading. They will always have their initial values until you actively replace them. Worse still, you may even end up saving empty entities in the database!
And there's another effect: relationship fixup won't occcur. Relationship fixup is the process by which EF connects all entities in the context by their navigation properties. When a User and a Licence are loaded separately, still User.License will be populated and vice versa. Unless of course, if License was initialized in the constructor. This is also true for 1:n associations. If Address would initialize a User in its constructor, User.Addresses would not be populated!
Entity Framework core
Relationship fixup in Entity Framework core (2.1 at the time of writing) isn't affected by initialized reference navigation properties in constructors. That is, when users and addresses are pulled from the database separately, the navigation properties are populated.
However, lazy loading does not overwrite initialized reference navigation properties.
In EF-core 3, initializing a reference navigation property prevents Include from working properly.
So, in conclusion, also in EF-core, initializing reference navigation properties in constructors may cause trouble. Don't do it. It doesn't make sense anyway.
In all my projects I follow the rule - "Collections should not be null. They are either empty or have values."
First example is possible to have when creation of these entities is responsibility of third-part code (e.g. ORM) and you are working on a short-time project.
Second example is better, since
you are sure that entity has all properties set
you avoid silly NullReferenceException
you make consumers of your code happier
People, who practice Domain-Driven Design, expose collections as read-only and avoid setters on them. (see What is the best practice for readonly lists in NHibernate)
Q1: Which one is better? why? Pros and Cons?
It is better to expose not-null colections since you avoid additional checks in your code (e.g. Addresses). It is a good contract to have in your codebase. But it os OK for me to expose nullable reference to single entity (e.g. License)
Q2: In second approach there would be stack overflow if the License class has a reference to User class too. It means we should have one-way reference.(?) How we should decide which one of the navigation properties should be removed?
When I developed data mapper pattern by myself I tryed to avoid bidirectional references and had reference from child to parent very rarely.
When I use ORMs it is easy to have bidirectional references.
When it is needed to build test-entity for my unit-tests with bidirectional reference set I follow the following steps:
I build parent entity with emty children collection.
Then I add evey child with reference to parent entity into children collection.
Insted of having parameterless constructor in License type I would make user property required.
public class License
{
public License(User user)
{
this.User = user;
}
public int Id { get; set; }
public string Key { get; set; }
public DateTime Expirtion { get; set; }
public virtual User User { get; set; }
}
It's redundant to new the list, since your POCO is depending on Lazy Loading.
Lazy loading is the process whereby an entity or collection of entities is automatically loaded from the database the first time that a property referring to the entity/entities is accessed. When using POCO entity types, lazy loading is achieved by creating instances of derived proxy types and then overriding virtual properties to add the loading hook.
If you would remove the virtual modifier, then you would turn off lazy loading, and in that case your code no longer would work (because nothing would initialize the list).
Note that Lazy Loading is a feature supported by entity framework, if you create the class outside the context of a DbContext, then the depending code would obviously suffer from a NullReferenceException
HTH
The other answers fully answer the question, but I'd like to add something since this question is still relevant and comes up in google searches.
When you use the "code first model from database" wizard in Visual Studio all collections are initialized like so:
public partial class SomeEntity
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public SomeEntity()
{
OtherEntities = new HashSet<OtherEntity>();
}
public int Id { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<OtherEntity> OtherEntities { get; set; }
}
I tend to take wizard output as basically being an official recommendation from Microsoft, hence why I'm adding to this five-year-old question. Therefore, I'd initialize all collections as HashSets.
And personally, I think it'd be pretty slick to tweak the above to take advantage of C# 6.0's auto-property initializers:
public virtual ICollection<OtherEntity> OtherEntities { get; set; } = new HashSet<OtherEntity>();
Q1: Which one is better? why? Pros and Cons?
The second variant when virtual properties are set inside an entity constructor has a definite problem which is called "Virtual member call in a constructor".
As for the first variant with no initialization of navigation properties, there are 2 situations depending on who / what creates an object:
Entity framework creates an object
Code consumer creates an object
The first variant is perfectly valid when Entity Framework creates a object,
but can fail when a code consumer creates an object.
The solution to ensure a code consumer always creates a valid object is to use a static factory method:
Make default constructor protected. Entity Framework is fine to work with protected constructors.
Add a static factory method that creates an empty object, e.g. a User object, sets all properties, e.g. Addresses and License, after creation and returns a fully constructed User object
This way Entity Framework uses a protected default constructor to create a valid object from data obtained from some data source and code consumer uses a static factory method to create a valid object.
I use the answer from this Why is my Entity Framework Code First proxy collection null and why can't I set it?
Had problems with constructor initilization. Only reason I do this is to make test code easier. Making sure collection is never null saves me constantly initialising in tests etc
Let's say I have a class Order. An Order can be finished by calling Order.finish() method. Internally, when an Order is finished, a finishing date is set:
Order.java
public void finish() {
finishingDate = new Date();
}
In the application's business logic, there is no need to expose an Order's finishingDate, so it is a private field without a getter.
Imagine that after finishing an Order, I want to update it in a database. For instance, I could have a DAO with an update method:
OrderDao.java
public void update(Order order) {
//UPDATE FROM ORDERS SET ...
}
In that method, I need the internal state of the Order, in order to update the table fields. But I said before that there is no need in my business logic to expose Order's finishingDate field.
If I add a Order.getFinishingDate() method:
I'm changing the contract of Order class without adding business value, ubt for "technical" reasons (an UPDATE in a database)
I'm violating the principle of encapsulation of object oriented programming, since I'm exposing internal state.
How do you solve this? Do you consider adding getters (like "entity" classes in ORM do) is acceptable?
I have seen a different approach where class itself (implementation) knows even how to persist itself. Something like this (very naive example, it's just for the question):
public interface Order {
void finish();
boolean isFinished();
}
public class DbOrder implements Order {
private final int id;
private final Database db;
//ctor. An implementation of Database is injected
#Override
public void finish() {
db.update("ORDERS", "FINISHING_DATE", new Date(), "ID=" + id);
}
#Override
public boolean isFinished() {
Date finishingDate = db.select("ORDERS", "FINISHING_DATE", "ID=" + id);
return finishingDate != null;
}
}
public interface Database {
void update(String table, String columnName, Object newValue, String whereClause);
void select(String table, String columnName, String whereClause);
}
Apart from the performance issues (actually, it can be cached or something), I like this approach but it forces us to mock many things when testing, since all the logic is not "in-memory". I mean, the required data to "execute" the logic under test is not just a field in memory, but it's provided by an external component: in this case, the Database.
This is an excellent observation in my opinion. No, I don't consider adding any methods just for technical reasons acceptable, especially getters. I must admit however, that the majority of people I've worked with would just add the getters and would not think about it in detail as you do.
Ok, so how do we solve the problem of persisting something we can't get access to? Well, just ask the object to persist itself.
You can have a persist() (or whatever) method on the object itself. This is ok, since it is part of the business. If it is not, think about what is. Is it sendToBackend() maybe? This does not mean you have to put the details of persistence into the object!
The method itself can be as removed from actual persistence as you like. You can give it interfaces as parameters, or it can return some other object that can be used further down the line.
See these other answers about the same problems for presentation:
Returning a Data Structure to Display information
Encapsulation and Getters
I've been modeling a domain for a couple of days now and not been thinking at all at persistance but instead focusing on domain logic. Now I'm ready to persist my domain objects, some of which contains IEnumerable of child entities. Using RavenDb, the persistance is 'easy', but when loading my objects back again, all of the IEnumerables are empty.
I've realized this is because they don't have any property setters at all, but instead uses a list as a backing field. The user of the domain aggregate root can add child entities through a public method and not directly on the collection.
private readonly List<VeryImportantPart> _veryImportantParts;
public IEnumerable<VeryImportantPart> VeryImportantParts { get { return _veryImportantParts; } }
And the method for adding, nothing fancy...
public void AddVeryImportantPart(VeryImportantPart part)
{
// some logic...
_veryImportantParts.Add(part);
}
I can fix this by adding a private/protected setter on all my IEnumerables with backing fields but it looks... well... not super sexy.
private List<VeryImportantPart> _veryImportantParts;
public IEnumerable<VeryImportantPart> VeryImportantParts
{
get { return _veryImportantParts; }
protected set { _veryImportantParts = value.ToList(); }
}
Now the RavenDb json serializer will populate my objects on load again, but I'm curious if there isn't a cleaner way of doing this?
I've been fiddeling with the JsonContractResolver but haven't found a solution yet...
I think I've found the root cause of this issue and it's probably due to the fact that many of my entities were created using:
protected MyClass(Guid id, string name, string description) : this()
{ .... }
public static MyClass Create(string name, string description)
{
return new MyClass(Guid.NewGuid(), name, description);
}
When deserializing, RavenDb/Json.net couldn't rebuild my entities in a proper way...
Changing to using a public constructor made all the difference.
Do you need to keep a private backing field? Often an automatic property will do.
public IList<VeryImportantPart> VeryImportantParts { get; protected set; }
When doing so, you may want to initialize your list in the constructor:
VeryImportantParts = new List<VeryImportantPart>();
This is optional, of course, but it allows you to create a new class and start adding to the list right away, before it is persisted. When Raven deserializes a class, it will use the setter to overwrite the default blank list, so this just helps with the first store.
You certainly won't be able to use a readonly field, as it couldn't be replaced during deserialization. It might be possible to write a contract resolver or converter that fills an existing list rather than creating a new one, but that seems like a rather complex solution.
Using an automatic property can add clarity to your code anyway - as it is less confusing whether to use the field or the property.
Say I have a common pattern with a Customer object and a SalesOrder object. I have corresponding SalesOrderContract and CustomerContract objects that are similar, flatter objects used to serialize through a web service
public class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
public Address ShippingAddress { get; set; }
//more fields...
}
public class Order
{
public int OrderId { get; set; }
public Customer Customer { get; set;
// etc
}
And my sales order contract looks like this
public class OrderContract
{
public int OrderId { get; set; }
public int CustomerId { get; set; }
}
public class OrderTranslator
{
public static Order ToOrder(OrderContract contract)
{
return new Order { OrderId = contract.OrderId };
// just translate customer id or populate entire Customer object
}
}
I have a layer inbetween the service layer and business object layer that translates between the two. My question is this...do I populate the Order.Customer object on the other end since the Order table just needs the customer id. I don't carry the entire customer object in the OrderContract because it's not necessary and too heavy. But, as part of saving it, I have to validate that it's indeed a valid customer. I can do a few things
Populate the Order.Customer object completely based on the CustomerId when I translate between contract and entity.. This would require calling the CustomerRepository in a helper class that translates between entities and contracts. Doesn't feel right to me. Translator should really just be data mapping.
Create a domain service for each group of operations that performs the validation needed without populating the Order.Customer. This service would pull the Customer object based on Order.CustomerId and check to see if it's valid. Not sure on this because a sales order should be able to validate itself, but it's also not explicitly dealing with Orders as it also deals with Customers so maybe a domain service?
Create a seperate property Order.CustomerId and lazy load the customer object based on this.
Populate Order.Customer in from a factory class. Right now my factory classes are just for loading from database. I'm not really loading from datacontracts, but maybe it makes sense?
So the question is two part...if you have association properties in your enties that will be required to tell if something is completely valid before saving, do you just populate them? If you do, where you do actually do that because the contract/entity translator feels wrong?
The bottom line is that I need to be able to do something like
if (order.Customer == null || !order.Customer.IsActive)
{
//do something
}
The question is where does it make sense to do this? In reality my Order object has a lot of child entities required for validation and I don't want things to become bloated. This is why I'm considering making domain services to encapsulate validation since it's such a huge operation in my particular case (several hundred weird rules). But I also don't want to remove all logic making my objects just properties. Finding the balance is tough.
Hope that makes sense. If more background is required, let me know.
You have a couple of things going on here. I think part of the issue is mainly how you appear to have arranged your Translator class. Remember, for an entity, the whole concept is based on instance identity. So a Translator for an entity should not return a new object, it should return the correct instance of the object. That typically means you have to supply it with that instance in the first place.
It is perhaps useful to think in terms of updates vs creating a new object.
For an update the way I would structure this operation is as follows: I would have the web service that the application calls to get and return the contract objects. This web service calls both repositories and Translators to do it's work. The validation stays on the domain object.
In code an update would look something like the following.
Web Service:
[WebService]
public class OrderService
{
[WebMethod]
public void UpdateOrder(OrderContract orderContract)
{
OrderRepository orderRepository = new OrderRepository(_session);
// The key point here is we get the actual order itself
// and so Customer and all other objects are already either populated
// or available for lazy loading.
Order order = orderRepository.GetOrderByOrderContract(orderContract);
// The translator uses the OrderContract to update attribute fields on
// the actual Order instance we need.
OrderTranslator.OrderContractToOrder(ref order, orderContract);
// We now have the specific order instance with any properties updated
// so we can validate and then persist.
if (order.Validate())
{
orderRepository.Update(order);
}
else
{
// Whatever
}
}
}
Translator:
public static class OrderTranslator
{
public static void OrderContractToOrder(ref Order order, OrderContract orderContract)
{
// Here we update properties on the actual order instance passed in
// instead of creating a new Order instance.
order.SetSomeProperty(orderContract.SomeProperty);
// ... etc.
}
}
The key concept here is because we have an entity, we are getting the actual Order, the instance of the entity, and then using the translator to update attributes instead of creating a new Order instance. Because we are getting the original Order, not creating a new instance, presumably we can have all the associations either populated or populated by lazy load. We do not have to recreate any associations from an OrderContract so the issue goes away.
I think the other part of the issue may be your understanding of how a factory is designed. It is true that for entities a Factory may not set all the possible attributes - the method could become hopelessly complex if it did.
But what a factory is supposed to do is create all the associations for a new object so that the new object returned is in a valid state in terms of being a full and valid aggregate. Then the caller can set all the other various and sundry "simple" attributes.
Anytime you have a Factory you have to make decisions about what parameters to pass in. Maybe in this case the web service gets the actual Customer and passes it to the factory as a parameter. Or Maybe the web service passes in an Id and the factory is responsible for getting the actual Customer instance. It will vary by specific situation but in any case, however it gets the other objects required, a factory should return at minimum a fully populated object in terms of it's graph, i.e all relationships should be present and traversible.
In code a possible example of new Order creation might be:
[WebService]
public class OrderService
{
[WebMethod]
public void SaveNewOrder(OrderContract orderContract)
{
// Lets assume in this case our Factory has a list of all Customers
// so given an Id it can create the association.
Order order = OrderFactory.CreateNewOrder(orderContract.CustomerId);
// Once again we get the actual order itself, albeit it is new,
// and so Customer and all other objects are already either populated
// by the factory create method and/or are available for lazy loading.
// We can now use the same translator to update all simple attribute fields on
// the new Order instance.
OrderTranslator.OrderContractToOrder(ref order, orderContract);
// We now have the new order instance with all properties populated
// so we can validate and then persist.
if (order.Validate())
{
//Maybe you use a Repository - I use a unit of work but the concept is the same.
orderRepository.Save(order);
}
else
{
//Whatever
}
}
}
So, hope that helps?
I don't know why I started thinking about this, but now I can't seem to stop.
In C# - and probably a lot of other languages, I remember that Delphi used to let you do this too - it's legal to write this syntax:
class WeirdClass
{
private void Hello(string name)
{
Console.WriteLine("Hello, {0}!", name);
}
public string Name
{
set { Hello(name); }
}
}
In other words, the property has a setter but no getter, it's write-only.
I guess I can't think of any reason why this should be illegal, but I've never actually seen it in the wild, and I've seen some pretty brilliant/horrifying code in the wild. It seems like a code smell; it seems like the compiler should be giving me a warning:
CS83417: Property 'Name' appears to be completely useless and stupid. Bad programmer! Consider replacing with a method.
But maybe I just haven't been doing this long enough, or have been working in too narrow a field to see any examples of the effective use of such a construct.
Are there real-life examples of write-only properties that either cannot be replaced by straight method calls or would become less intuitive?
My first reaction to this question was: "What about the java.util.Random#setSeed method?"
I think that write-only properties are useful in several scenarios. For example, when you don't want to expose the internal representation (encapsulation), while allowing to change the state of the object. java.util.Random is a very good example of such design.
Code Analysis (aka FxCop) does give you a diagnostic:
CA1044 : Microsoft.Design : Because
property 'WeirdClass.Name' is write-only,
either add a property getter with an
accessibility that is greater than or
equal to its setter or convert this
property into a method.
Write-only properties are actually quite useful, and I use them frequently. It's all about encapsulation -- restricting access to an object's components. You often need to provide one or more components to a class that it needs to use internally, but there's no reason to make them accessible to other classes. Doing so just makes your class more confusing ("do I use this getter or this method?"), and more likely that your class can be tampered with or have its real purpose bypassed.
See "Why getter and setter methods are evil" for an interesting discussion of this. I'm not quite as hardcore about it as the writer of the article, but I think it's a good thing to think about. I typically do use setters but rarely use getters.
I have code similar to the following in an XNA project. As you can see, Scale is write-only, it is useful and (reasonably) intuitive and a read property (get) would not make sense for it. Sure it could be replaced with a method, but I like the syntax.
public class MyGraphicalObject
{
public double ScaleX { get; set; }
public double ScaleY { get; set; }
public double ScaleZ { get; set; }
public double Scale { set { ScaleX = ScaleY = ScaleZ = value; } }
// more...
}
One use for a write-only property is to support setter dependency injection, which is typically used for optional parameters.
Let's say I had a class:
public class WhizbangService {
public WhizbangProvider Provider { set; private get; }
}
The WhizbangProvider is not intended to be accessed by the outside world. I'd never want to interact with service.Provider, it's too complex. I need a class like WhizbangService to act as a facade. Yet with the setter, I can do something like this:
service.Provider = new FireworksShow();
service.Start();
And the service starts a fireworks display. Or maybe you'd rather see a water and light show:
service.Stop();
service.Provider = new FountainDisplay(new StringOfLights(), 20, UnitOfTime.Seconds);
service.Start();
And so on....
This becomes especially useful if the property is defined in a base class. If you chose construction injection for this property, you'd need to write a constructor overload in any derived class.
public abstract class DisplayService {
public WhizbangProvider Provider { set; private get; }
}
public class WhizbangService : DisplayService { }
Here, the alternative with constructor injection is:
public abstract class DisplayService {
public WhizbangProvider Provider;
protected DisplayService(WhizbangProvider provider) {
Provider = provider ?? new DefaultProvider();
}
}
public class WhizbangService : DisplayService {
public WhizbangService(WhizbangProvider provider)
: base(provider)
{ }
}
This approach is messier in my opinion, because you need to some of the internal workings of the class, specifically, that if you pass null to the constructor, you'll get a reasonable default.
In MVP pattern it is common to write a property with a setter on the view (no need for a getter) - whenever the presenter sets it content the property will use that value to update some UI element.
See here for a small demonstration:
public partial class ShowMeTheTime : Page, ICurrentTimeView
{
protected void Page_Load(object sender, EventArgs e)
{
CurrentTimePresenter presenter = new CurrentTimePresenter(this);
presenter.InitView();
}
public DateTime CurrentTime
{
set { lblCurrentTime.Text = value.ToString(); }
}
}
The presenter InitView method simply sets the property's value:
public void InitView()
{
view.CurrentTime = DateTime.Now;
}
Making something write-only is usefulwhenever you're not supposed to read what you write.
For example, when drawing things onto the screen (this is precisely what the Desktop Window Manager does in Windows):
You can certainly draw to a screen, but you should never need to read back the data (let alone expect to get the same design as before).
Now, whether write-only properties are useful (as opposed to methods), I'm not sure how often they're used. I suppose you could imagine a situation with a "BackgroundColor" property, where writing to it sets the background color of the screen, but reading makes no sense (necessarily).
So I'm not sure about that part, but in general I just wanted to point out that there are use cases for situations in which you only write data, and never read it.
Although the .NET design guidelines recommend using a method ("SetMyWriteOnlyParameter") instead of a write-only property, I find write-only properties useful when creating linked objects from a serialised representation (from a database).
Our application represents oil-field production systems. We have the system as a whole (the "Model" object) and various Reservoir, Well, Node, Group etc objects.
The Model is created and read from database first - the other objects need to know which Model they belong to. However, the Model needs to know which lower object represents the Sales total. It makes sense for this information to be stored a Model property. If we do not want to have to do two reads of Model information, we need to be able to read the name of Sales object before its creation. Then, subsequently, we set the "SalesObject" variable to point to the actual object (so that, e.g., any change by the user of the name of this object does not cause problems)
We prefer to use a write-only property - 'SalesObjectName = "TopNode"' - rather than a method - 'SetSalesObjectName("TopNode") - because it seems to us that the latter suggests that the SalesObject exists.
This is a minor point, but enough to make us want to use a Write-Only property.
As far as I'm concerned, they don't. Every time I've used a write-only property as a quick hack I have later come to regret it. Usually I end up with a constructor or a full property.
Of course I'm trying to prove a negative, so maybe there is something I'm missing.
I can't stop thinking about this, either. I have a use case for a "write-only" property. I can't see good way out of it.
I want to construct a C# attribute that derives from AuthorizeAttribute for an ASP.NET MVC app. I have a service (say, IStore) that returns information that helps decide if the current user should be authorized. Constructor Injection won't work, becuase
public AllowedAttribute: AuthorizeAttribute
{
public AllowedAttribute(IStore store) {...}
private IStore Store { get; set; }
...
}
makes store a positional attribute parameter, but IStore is not a valid attribute parameter type, and the compiler won't build code that is annotated with it. I am forced to fall back on Property Setter Injection.
public AllowedAttribute: AuthorizeAttribute
{
[Inject] public IStore Store { private get; set; }
...
}
Along with all the other bad things about Property Setter instead of Constructor Injection, the service is a write-only property. Bad enough that I have to expose the setter to clients that shouldn't need to know about the implementation detail. It wouldn't do anybody any favors to let clients see the getter, too.
I think that the benefit of Dependency Injection trumps the guidelines against write-only properties for this scenario, unless I am missing something.
I just came across that situation when writing a program that reads data from a JSON database (Firebase). It uses Newtonsoft's Json.NET to populate the objects. The data are read-only, i.e., once loaded they won't change. Also, the objects are only deserialized and won't be serialized again. There may be better ways, but this solution just looks reasonable for me.
using Newtonsoft.Json;
// ...
public class SomeDatabaseClass
{
// JSON object contains a date-time field as string
[JsonProperty("expiration")]
public string ExpirationString
{
set
{
// Needs a custom parser to handle special date-time formats
Expiration = Resources.CustomParseDateTime(value);
}
}
// But this is what the program will effectively use.
// DateTime.MaxValue is just a default value
[JsonIgnore]
public DateTime Expiration { get; private set; } = DateTime.MaxValue;
// ...
}
No, I can' imagine any case where they can't be replaced, though there might people who consider them to be more readable.
Hypothetical case:
CommunicationDevice.Response = "Hello, World"
instead of
CommunicationDevice.SendResponse("Hello, World")
The major job would be to perform IO side-effects or validation.
Interestingly, VB .NET even got it's own keyword for this weird kind of property ;)
Public WriteOnly Property Foo() As Integer
Set(value As Integer)
' ... '
End Set
End Property
even though many "write-only" properties from outside actually have a private getter.
I recently worked on an application that handled passwords. (Note that I'm not claiming that the following is a good idea; I'm just describing what I did.)
I had a class, HashingPassword, which contained a password. The constructor took a password as an argument and stored it in a private attribute. Given one of these objects, you could either acquire a salted hash for the password, or check the password against a given salted hash. There was, of course, no way to retrieve the password from a HashingPassword object.
So then I had some other object, I don't remember what it was; let's pretend it was a password-protected banana. The Banana class had a set-only property called Password, which created a HashingPassword from the given value and stored it in a private attribute of Banana. Since the password attribute of HashingPassword was private, there was no way to write a getter for this property.
So why did I have a set-only property called Password instead of a method called SetPassword? Because it made sense. The effect was, in fact, to set the password of the Banana, and if I wanted to set the password of a Banana object, I would expect to do that by setting a property, not by calling a method.
Using a method called SetPassword wouldn't have had any major disadvantages. But I don't see any significant advantages, either.
I know this has been here for a long time, but I came across it and have a valid (imho) use-case:
When you post parameters to a webapi call from ajax, you can simply try to fill out the parameters class' properties and include validation or whatsoever.
public int MyFancyWepapiMethod([FromBody]CallParams p) {
return p.MyIntPropertyForAjax.HasValue ? p.MyIntPropertyForAjax.Value : 42;
}
public class CallParams
{
public int? MyIntPropertyForAjax;
public object TryMyIntPropertyForAjax
{
set
{
try { MyIntPropertyForAjax = Convert.ToInt32(value); }
catch { MyIntPropertyForAjax = null; }
}
}
}
On JavaScript side you can simply fill out the parameters including validation:
var callparameter = {
TryMyIntPropertyForAjax = 23
}
which is safe in this example, but if you handle userinput it might be not sure that you have a valid intvalue or something similar.