.NET - It is possible to use DI with the State Pattern? - c#

I'm studying design patterns in .NET and currently i'm trying to implement the State Pattern. But today i got to a problem and i can't figure out how to fix this situation.
I have some state classes, all of them implementing the state interface. One of the last states should connect to a data base, through a service injected by the .NET API Startup class, to persist the data and finish up the process.
The problem is... because of the dependency injection that i need to be in the final state, i can't instanciate this state object to progress to this point. I don't know how to continue from there. I don't know if i'm using the pattern wrong or if the use of dependency injection in this pattern is the problem. I can't give all the details of the problem because my studie's project is a little big mess at this moment, so i made a quick mimic of the structure i'm trying to build in my application.
States interface and the OperatingClass who will execute the state behaviour:
public interface IOperationState
{
public int ExecuteOperation(OperatingClass operatingClass);
}
public class OperatingClass
{
public IOperationState OperationState { get; set; }
public int id { get; set; }
public double value { get; set; }
public OperatingClass(int id) //constructor
{
this.id = id;
value = 0;
OperationState = new StartingState();
}
public int Execute()
{
return OperationState.ExecuteOperation(this);
}
}
Main Service: is the service who my controller calls after receive the API Post Method:
public class MainService
{
public int ExecuteFullOperation(int id)
{
//Receives an id and execute the state transition till the end;
var operatingClass = new OperatingClass(id);
return operatingClass.Execute();
}
}
The classes who represents the states and do the respective actions:
public class StartingState : IOperationState
{
public int ExecuteOperation(OperatingClass operatingClass)
{
// Do something...
operatingClass.OperationState = new MiddleState();
return operatingClass.Execute();
}
}
public class MiddleState : IOperationState
{
public int ExecuteOperation(OperatingClass operatingClass)
{
//Do something with the value... let's supose the result is 123, but it does not matter rn;
operatingClass.value = 123;
//Here is the problem: FinalState needs the PersistenceService, who
//receives a injected class to acess the database;
operatingClass.OperationState = new FinalState();
//I want to execute it and return the sucess or failure of the persistence.
return operatingClass.Execute();
}
}
public class FinalState : IOperationState
{
private readonly IPersistenceService PersistenceService;
public FinalState(IPersistenceService persistenceService)
{
PersistenceService = persistenceService;
}
public int ExecuteOperation(OperatingClass operatingClass)
{
return PersistenceService.PersistData(operatingClass.id, operatingClass.value) ? 200 : 503;
}
}
Additional info: i made the PersistenceService be injected in the Startup.cs as a Transient (i dont know how to make it in another way at this moment).
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IPersistenceService, PersistenceService>();
// Irrelevant configurations for the question.
services.AddControllers();
}
Please, help me if you can. I'm having a hard time trying to figure it out by myself.
Thank you for your patience and for your time reading it.

Firstly, we need some simple factory which will supply all necessary dependencies by their type. So let's create types for states:
public enum StateType
{
Start,
Middle,
Final
}
And simple factory:
public class StateFactory
{
private Dictionary<StateType, IOperationState> _stateByType;
// you can inject these dependencies through DI like that:
// public StateFactory(StartingState startingState,
// MiddleState middleState, FinalState finalState,
// PersistenceService persistenceService)
public StateFactory()
{
_stateByType = new Dictionary<StateType, IOperationState>()
{
{ StateType.Start, new StartingState(this) },
{ StateType.Middle, new MiddleState(this) },
{ StateType.Final, new FinalState(new PersistenceService()) }
};
}
public IOperationState GetByType(StateType stateType) =>
_stateByType[stateType];
}
Then we should register all our dependencies:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IPersistenceService, PersistenceService>();
services.AddTransient<StartingState>();
services.AddTransient<MiddleState>();
services.AddTransient<FinalState>();
services.AddTransient<MainService>();
services.AddTransient<OperatingClass>();
services.AddTransient<PersistenceService>();
services.AddTransient<StateFactory>();
}
Our states would look like this:
public class StartingState : IOperationState
{
private StateFactory _factory;
public StartingState(StateFactory stateFactory)
{
_factory = stateFactory;
}
public int ExecuteOperation(OperatingClass operatingClass)
{
// Do something...
// operatingClass.OperationState = new MiddleState();
operatingClass.OperationState = _factory.GetByType(StateType.Middle);
return operatingClass.Execute();
}
}
And MiddleState would look like this:
public class MiddleState : IOperationState
{
private StateFactory _factory;
public MiddleState(StateFactory stateFactory)
{
_factory = stateFactory;
}
public int ExecuteOperation(OperatingClass operatingClass)
{
//Do something with the value... let's supose the result is 123,
// but it does not matter rn;
operatingClass.value = 123;
//Here is the problem: FinalState needs the PersistenceService, who
//receives a injected class to acess the database;
operatingClass.OperationState = _factory.GetByType(StateType.Final);
//I want to execute it and return the sucess or failure of the persistence.
return operatingClass.Execute();
}
}
And Final state should look like this:
public class FinalState : IOperationState
{
private readonly IPersistenceService _persistenceService;
public FinalState(IPersistenceService persistenceService)
{
_persistenceService = persistenceService;
}
public int ExecuteOperation(OperatingClass operatingClass)
{
return _persistenceService
.PersistData(operatingClass.id, operatingClass.value)
? 200
: 503;
}
}
And other classes sush as OperatingClass would use StateFactory too:
public class OperatingClass
{
public IOperationState OperationState { get; set; }
public int id { get; set; }
public double value { get; set; }
public OperatingClass(int id, StateFactory stateFactory) //constructor
{
this.id = id;
value = 0;
// OperationState = new StartingState();
OperationState = stateFactory.GetByType(StateType.Start);
}
public int Execute()
{
return OperationState.ExecuteOperation(this);
}
}
And it is necessary to create concrete example of PersistenceService:
public interface IPersistenceService
{
bool PersistData(int id, double value);
}
public class PersistenceService : IPersistenceService
{
public bool PersistData(int id, double value)
{
throw new NotImplementedException();
}
}

Related

Dependency injection in nested dynamic object creation?

I have a quite complex application with objects that are nested quite deep from Main and I would like to avoid passing all the dependencies down from the top-level objects and down to the bottom where it might be needed / used.
This is some sample code to illustrate, but is very simplified:
internal class Program
{
public interface IPriceList
{
double GetPrice();
}
public class PriceList : IPriceList
{
public double GetPrice() { return 4.3; }
}
public abstract class Condition
{
public abstract bool IsTrue();
}
public class A
{
private List<Condition> _conditions = new List<Condition>();
public A()
{
}
public void CreateConditionsFromJson()
{
// Read from JSON and dynamically create conditions (not as simple as below)
_conditions.Add(new PriceIsHigherCondition(3.4, ???))
}
}
public class PriceIsHigherCondition : Condition
{
double _price;
IPriceList _priceLIst;
public PriceIsHigherCondition(double price, IPriceList priceList)
{
_price = price;
_priceLIst = priceList;
}
public override bool IsTrue()
{
return _price > _priceLIst.GetPrice();
}
}
static void Main(string[] args)
{
// A is not created here, but deeper down
}
}
It's tempting to create a static class, set the member variables in Main and then access it in the constructors at the bottom level (the condition):
public static class ConditionDependencies
{
public static IPriceList PriceList { get; set; }
}
Any more elegant solution?
I kind of like this (even it might be an anti-pattern):
Define a public static class for dependencies:
public static class ConditionDependencies
{
public static IPriceList PriceList { get; set; }
}
In Main, setup the dependencies:
static void Main(string[] args)
{
// Setup dependencies
ConditionDependencies.PriceList = new PriceList();
}
In a constructor anywhere needing a dependency, just get it:
public class PriceIsHigherCondition : Condition
{
double _price;
IPriceList _priceLIst;
public PriceIsHigherCondition(double price)
{
// Inject Dependencies
_priceLIst = ConditionDependencies.PriceList;
_price = price;
}
public override bool IsTrue()
{
return _price > _priceLIst.GetPrice();
}
}
Is it an anti-pattern? Why? What are the pitfalls?

Change business layer class to be loosely coupled

I have below code I am working on. I am working on data access adon.net layer. I have problem with my business layer class called UserBAL. The problem is that I am creating instance of dal and dbmanager inside constructor of UserBAL. How can I change this to be loosely coupled for UserBAL? Hope you get my point.
public interface IEntity
{
int Id { get; set; }
int DoSomething(string one, int two);
}
public class User : IEntity
{
public int Id { get; set; }
public int DoSomething(string one, int two)
{
throw new NotImplementedException();
}
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
public class UserBal //busines logic
{
private readonly IRepositoryDal<User> _userRepositoryDal;
public UserBal()
{
_userRepositoryDal = new UserRepositoryDal(new DbManager("sqlserver?"));
}
public IEnumerable<User> SearchByName(string name)
{
return _userRepositoryDal.SearchByName(name);
}
}
interface IRepositoryDal<T> where T : IEntity
{
IEnumerable<T> SearchByName(string username);
T SearchById(string id);
void Update(T entity);
void Remove(T entity);
void Add(T entity);
}
public class UserRepositoryDal: IRepositoryDal<User>
{
private readonly IDbManager _dbManager;
public UserRepositoryDal(IDbManager dbManager)
{
//read from either singleton or configuration file !!
_dbManager = dbManager;
}
public IEnumerable<User> SearchByName(string username)
{
var parameters = new List<IDbDataParameter>
{
_dbManager.CreateParameter("#FirstName", 50, username, DbType.String),
};
var userDataTable = _dbManager.GetDataTable("storedpr2",
CommandType.StoredProcedure, parameters.ToArray());
foreach (DataRow dr in userDataTable.Rows)
{
var user = new User
{
Id = int.Parse(dr["Id"].ToString()),
Firstname = dr["Firstname"].ToString(),
Lastname = dr["LastName"].ToString(),
Email = dr["Email"].ToString()
};
yield return user;
}
}
public User SearchById(string id)
{
var parameters = new List<IDbDataParameter>
{
_dbManager.CreateParameter("#Id", 50, id, DbType.Int32),
};
var userDataTable = _dbManager.GetDataTable("storedpr2",
CommandType.StoredProcedure, parameters.ToArray());
return new User
{
Id = int.Parse(userDataTable.Rows[0]["Id"].ToString()),
Firstname = userDataTable.Rows[0]["Firstname"].ToString(),
Lastname = userDataTable.Rows[0]["LastName"].ToString(),
Email = userDataTable.Rows[0]["Email"].ToString()
};
}
public void Update(User entity)
{
throw new System.NotImplementedException();
}
public void Remove(User entity)
{
throw new System.NotImplementedException();
}
public void Add(User entity)
{
throw new System.NotImplementedException();
}
}
public partial class FrmLogin : Form
{
private readonly UserBal _userBal;
public FrmLogin()
{
InitializeComponent();
_userBal = new UserBal();
}
}
You should use dependency injection, and for required dependencies, you can use constructor injection, e.g:
public class UserBal
{
private readonly IRepositoryDal<User> _userRepositoryDal;
public UserBal(IRepositoryDal<User> userRepositoryDal)
{
_userRepositoryDal = userRepositoryDal
?? throw new ArgumentNullException(nameof(userRepositoryDal));
}
...
}
Dependency injection is the way to go. Here's a simplified example of your situation.
Given your classes could be like this:
public interface IEntity { }
public interface IRepositoryDal<T> where T : IEntity { }
public interface IDbManager { }
public class User : IEntity { }
public class UserBal //busines logic
{
[Injectivity.Attributes.Inject]
private IRepositoryDal<User> _userRepositoryDal;
}
public class UserRepositoryDal: IRepositoryDal<User>
{
[Injectivity.Attributes.Inject]
private IDbManager _dbManager;
}
public class DbManager : IDbManager
{
[Injectivity.Attributes.Construct()]
public DbManager([Injectivity.Attributes.Key("dbKey", typeof(string))] string x)
{
Console.WriteLine($"DbManager created with parameter \"{x}\"");
}
}
...then this code:
var context = Injectivity.Context.CreateRoot();
context.SetConfig<string>("dbKey", "sqlserver?");
context.SetFactory<IDbManager, DbManager>();
context.SetFactory<IRepositoryDal<User>, UserRepositoryDal>();
context.SetFactory<UserBal, UserBal>();
var user = context.Resolve<UserBal>();
...will produce this output:
DbManager created with parameter "sqlserver?"
Now, I've used a DI container that I wrote a number of years back. It's very flexible.
So the call to context.Resolve<UserBal>(); runs down the chain of seeing what needs to be injected to create all of the instances of all of the objects. Ultimately the creation of UserBal requires the DbManager to be created and hence the output.
You would normally not explicitly register each factory. Normally you would put attributes on all of the classes you want to register and then use context.Register(Assembly.LoadFrom("My.DLL")); or create an XML config file and call context.LoadConfig(XDocument.Load("config.xml"));.
You can even do things like this:
context.SetDecorator<IRepositoryDal<User>, UserRepositoryDalDecorator>();
This will cause all calls to context.Resolve<IRepositoryDal<User>>() or [Inject] attributes to automatically wrap the real instances in this decorator. Ideal to intercepting method calls for debugging purposes.

Cast object from an interface to its implementation

I have the following code:
public interface BaseInterface
{
int ID { get; }
}
public interface SpecialInterface1 : BaseInterface
{
int price { get; }
}
public interface SpecialInterface1 : BaseInterface
{
int xyz { get; }
}
public class Implementation1 : SpecialInterface
{
int price { get; }
int ID { get; internal set; }
}
public class Implementation2 : SpecialInterface
{
int xyz { get; }
int ID { get; internal set; }
}
Now in a Management class I want to add the objects that implement BaseInterface into a List.
I know that I can use as or is to cast the interface to an implementation, but in my project, I have about 10 special interfaces with an implementation each so I would have to write a really big if statements.
public void Add(BaseInterface u, int id)
{
if (u is Implementation1)
{
((Implementation1)u).ID = id;
Units.Add(u);
}
if (u is Implementation2)
{
((Implementation2)u).ID = id;
Units.Add(u);
}
}
My goal is that the id is not changeable outside the implementation and I would provide only the interfaces outside my dll so none can change the id.
A solution would be to add an extra interface. This eliminates the internal setter in your implementation.
internal interface IChangeID
{
void SetID(int id);
}
public interface IBaseInterface
{
int ID { get; }
}
public class Implementation : IBaseInterface,
IChangeID
{
public void SetID(int id) { ID = id; }
public int ID { get; private set; }
}
Only the real implementations should implement IChangeID. Returning IBaseInterface or ISpecialInterface will hide the setter, because those interfaces do not inherit from IChangeID.
This would change your add into:
public void Add(BaseInterface u, int id)
{
((IChangeID)u).SetID(id);
Units.Add(u);
}
If you do want to return the concrete types, not interfaces. You could implement the given interface explicit. This will hide the set method even from the concrete implementation.
public class Implementation : IBaseInterface,
IChangeID
{
void IChangeID.SetID(int id) { ID = id; }
public int ID { get; private set; }
}
var obj = new Implementation();
obj.SetID() // This WILL NOT Compile
If you don't want to modify the interfaces and implementations, you could use C# 7's pattern matching to access the implementation type without casting. It requires 3 lines per implementation type but avoids modifying the classes:
public void Add(BaseInterface u, int id)
{
switch(u)
{
case Implementation1 u1:
u1.ID = id;
break;
case Implementation2 u1:
u1.ID = id;
break;
default :
throw new ArgumentException("Unexpected implementation!");
}
Units.Add(u);
}
The obvious disadvantage is that the code will have to be modified if a new implementation is added.
Another option is to use dynamic, losing type safety. This will fail at runtime if some implementation doesn't have a setter (eg because it was replaced by constructor initialization)
public void Add(BaseInterface u, int id)
{
dynamic x =u;
x.ID=id;
Units.Add(x);
}
While I like this answer the best,
I recommend making the ID a required parameter of all the implementation's constructors, and then to use a factory pattern to generate any instance you require. This makes any instance without the ID set throw an exception at compile time rather than runtime reducing the probability of exceptions.
Here is a simple example that gets you what you want without an additional interface. Should you choose you can combine my answer with #Iqon's answer.
public interface IInterface
{
int ID { get; }
}
internal class InternalImplementation: IInterface {
public InternalImplementation(int ID) { this.ID = ID; }
public int ID { get; set; }
}
public class MyImplementationFactoryService {
public IInterface Create() {
int id = 1 // Or however you get your ID, possibly from a DB query?
return new InternalImplementation(id);
}
public IInterface Create(type|enum createtype) {
// return type based on typeof or enum
}
}
In case you want to use reflection to set property, code below may help
public interface IBaseInterface
{
int ID { get; }
}
public class Impl1 : IBaseInterface
{
public int ID { get; internal set; }
public int Price {get; set;}
}
public class Impl2 : IBaseInterface
{
public int ID { get { return 0;} }
public int Subscription {get; set;}
}
public class Program
{
public static void Main(string[] args)
{
IBaseInterface obj1 = new Impl1();
SetProperty(obj1, "ID", 100);
Console.WriteLine("Object1 Id is {0}", obj1.ID);
IBaseInterface obj2 = new Impl2();
SetProperty(obj2, "ID", 500);
Console.WriteLine("Object2 Id is {0}", obj2.ID);
}
private static void SetProperty(IBaseInterface obj, string propertyName, object id){
if(obj.GetType().GetProperty(propertyName).CanWrite) {
obj.GetType().GetProperty(propertyName).SetValue(obj, id);
Console.WriteLine("CanWrite property '{0}' : {1}" , propertyName, obj.GetType().GetProperty(propertyName).CanWrite);
}
}
}
Output
CanWrite property 'ID' : True
Object1 Id is 100
Object2 Id is 0

ServiceStack GetRequestFilterAttributes NullReference

I'm trying to use the new API approach for ServiceStack and I'm building a test console application to host it. So far I have the route instantiating the request DTO, but before the request reaches my service's Any method, I get this exception:
Error Code NullReferenceException
Message Object reference not set to an instance of an object.
Stack Trace at ServiceStack.WebHost.Endpoints.Utils.FilterAttributeCache.GetRequestFilterAttributes(Type requestDtoType) at
ServiceStack.WebHost.Endpoints.EndpointHost.ApplyRequestFilters(IHttpRequest httpReq, IHttpResponse httpRes, Object requestDto) at
ServiceStack.WebHost.Endpoints.RestHandler.ProcessRequest(IHttpRequest httpReq, IHttpResponse httpRes, String operationName)
Below is my test Service using IReturn and Service (at this point I'm only trying to return hard-coded results to see it working)
[DataContract]
public class AllAccounts : IReturn<List<Account>>
{
public AllAccounts()
{
}
}
[DataContract]
public class AccountTest : IReturn<string>
{
public AccountTest()
{
this.Id = 4;
}
[DataMember]
public int Id { get; set; }
}
public class AccountService : Service
{
public AccountService()
{
}
public object Any(AccountTest test)
{
return "hello";
}
public object Any(AllAccounts request)
{
var ret = new List<Account> {new Account() {Id = 3}};
return ret;
}
}
All ServiceStack references come from NuGet. I get the same error with either route. Any suggestions?
It might help to see your AppHost code and the code in your Configure() method. Nothing you provided in the code above stands out. Below is how I would set up a simple Console app using the code/classes you have provided.
Initialize and Start the ServiceStack AppHost
class Program
{
static void Main(string[] args)
{
var appHost = new AppHost();
appHost.Init();
appHost.Start("http://*:1337/");
System.Console.WriteLine("Listening on http://localhost:1337/ ...");
System.Console.ReadLine();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
}
}
Inherit from AppHostHttpListenerBase and Configure (not configuring anything for this example)
public class AppHost : AppHostHttpListenerBase
{
public AppHost() : base("Test Console", typeof(AppHost).Assembly) { }
public override void Configure(Funq.Container container)
{
}
}
Dto/Request classes
public class Account
{
public int Id { get; set; }
}
[Route("/AllAccounts")]
[DataContract]
public class AllAccounts : IReturn<List<Account>>
{
public AllAccounts()
{
}
}
[Route("/AccountTest")]
[DataContract]
public class AccountTest : IReturn<string>
{
public AccountTest()
{
this.Id = 4;
}
[DataMember]
public int Id { get; set; }
}
Service code to handle your requests - URLS: localhost:1337/AllAccounts & localhost:1337/AccountTest
public class AccountService : Service
{
public AccountService()
{
}
public object Any(AccountTest test)
{
return "hello";
}
public object Any(AllAccounts request)
{
var ret = new List<Account> { new Account() { Id = 3 } };
return ret;
}
}

C#: Confusion about Interfaces, Implementation and Inheritance

I'm wondering about what's the way to go, if I need to publicate data-interfaces but want to use them internal with extended calculated properties. To make it clearer:
// The public interface
public interface IData
{
int Property { get; }
}
// The internal interface
internal interface IExtendedData : IData
{
int ExtendedProperty { get; }
}
// The assumed implementation of someone using my interface
public class Data : IData
{
public Data(int a)
{
Property = a;
}
public int Property
{
get;
private set;
}
public override string ToString()
{
return Property.ToString();
}
}
// My implementation
internal class ExtendedData : IExtendedData
{
public ExtendedData(int a)
{
Property = a;
}
public int Property
{
get;
private set;
}
public int ExtendedProperty
{
get
{
return 2 * Property;
}
}
public override string ToString()
{
return Property.ToString() + ExtendedProperty.ToString();
}
}
// publicated by me, for the person who uses my dll
public static class Calculations
{
public static int DoSomeCalculation(IData data, int parameter)
{
// This probably don't work, but maybe shows what I want to do
IExtendedData tempData = (ExtendedData)data;
return tempData.ExtendedProperty * parameter;
}
}
I'm realy frustrated, cause I feel like missing some basical programing skills.
You could solve this problem by implementing ExtendedData as a Wrapper for a class implementing IData
internal class ExtendedData : IExtendedData
{
private IData data;
public ExtendedData(IData data)
{
this.data = data;
}
public int Property
{
get { return data.Property; }
private set { data.Property = value; }
}
public int ExtendedProperty
{
get
{
return 2 * Property;
}
}
}
and use this in DoSomeCalculation like
IExtendedData tempData = new ExtendedData(data);
ExtendedData could inherit from Data:
class ExtendedData : Data
{...}
And for creation of a Data object you add a factory like so:
public class DataFactory
{
public IData CreateData()
{
return new ExtendedData();
}
}
User have to create all its Data objects by this factory. You can ensure it by making Data's constructor internal.
In your DLL you can then cast to ExtendedData.

Categories