Block access to methods if certain constructor is called versus passing in unnecessary parameter to class?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP

Block access to methods if certain constructor is called versus passing in unnecessary parameter to class?



I have a class that contains 2 separate methods: Run and Fetch. The run method iterates over each of the object's widgets and calls the widget's Execute function. Each of the widgets are self-contained, and make their own data calls.


Run


Fetch


Execute



However, there is another methods, Fetch, that accesses the database through a logic layer to populate the widgets with data. These two methods are called at completely different times, and at different points in the application.


Fetch



When we call the run method, we do not need to pass the contexts into the main object, but we do need the contexts in order to fetch the data. What would be the best practice in this scenario? Having a single constructor that always requires the contexts even when they aren't required, or having multiple constructors and throwing an exception when a method is called without the contexts being populated?


run





Sounds like a separation of concerns issue. I'd suggest that the class that executes the widgets should be separate from the class that fetches information from the DB.
– juharr
6 hours ago






It looks like contexts is a static variable which you can set to null at startup and then test if it is null to determine if you need to get the data from the database.
– jdweng
6 hours ago





Why is it necessary to call Fetch? Can you simply have Run call Fetch internally assuming it's idempotent? Would breaking this up into 2 classes make more sense?
– Matthew
6 hours ago


Fetch


Run


Fetch





@Matthew We effectively have a Report object that contains a list of widgets. When we call the Run method, it causes the report widgets to execute and store their result sets to the database. This process can be fairly long running, so we have a polling process checking the status. When it's complete, we call Fetch to populate the data.
– JD Davis
5 hours ago


Report


Run


Fetch




1 Answer
1



Rather than attempting to block calls based on multiple constructors, and
depending on what IoC container you are using, you can explore the use of Lazy dependencies. Autofac for instance supports lazy initialization. This enables the scenario that dependencies (which can be rather expensive to spin up) are only resolved if/when they are needed.



I use them extensively to simplify my unit testing scenarios.


private MyDbContext _myDbContext = null;
private readonly Lazy<MyDbContext> _lazyMyDbContext = null;
public MyDbContext MyDbContext

get return _myDbContext ?? _lazyMyDbContext?.Value ?? throw new DependencyNullException("MyDbContext");
set _myDbContext = value;


public MyClass(Lazy<MyDbContext> myDbContext = null)

_lazyMyDbContext = myDbContext;



Above is the more test-friendly implementation. DependencyNullException is a custom exception similar to ArgumentNullException. (Favourable to finding a NullReferenceException raised somewhere) You can boil it down to:


private readonly Lazy<MyDbContext> _lazyMyDbContext = null;
private MyDbContext MyDbContext
{
get return _lazyMyDbContext?.Value ?? throw new DependencyNullException("MyDbContext");

public MyClass(Lazy<MyDbContext> myDbContext)

_lazyMyDbContext = myDbContext;



This ensures that dependencies are spun up as needed, but also simplifies unit tests for classes that may have more than a couple dependencies since tests don't need to mock every dependency to satisfy the constructor and just initialize and set needed mocks via the property setters prior to executing the scenario.






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

Executable numpy error

PySpark count values by condition

Mass disable jenkins jobs