I have 1 long running process wrapped inside a method and it is for 2 different types like below:
- Type1
- Type2
Code:
public interface IBaseType
{
MyResult LongRunningProcess(int jobId,int noOfTimes); //doenst save long running process data in database.just returns the results to consumer
void LongRunningProcess(int noOfTimes); //Save results of long running process in database.Background job with on-demand as well as scheduled
}
public class Type1 : IBaseType
{
public void LongRunningProcess(int jobId,int noOfTimes)
{
try
{
//Step1 :
var type1Manager = new Type1Manager(params);
for (int i = 0; i < noOfTimes; i++)
{
var con = ConnectionFactory.OpenConnection();
type1Manager.Start(con);
//Save results of those processing
}
//Step2:
IVersioning versioning = new Versioning();
string version = versioning.GetVersion();
using (connection = new SqlConnection(connectionString))
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
try
{
Repository.UpdateVariantVersioning(connection, transaction,jobId, version);
Repository.UpdateCategoryWithVersion(connection, transaction,versioning.Category,version);
transaction.Commit();
}
catch(Exception ex)
{
transaction.Rollback();
//code to delete everything that has been performed in step1
throw ex;
}
}
}
}
catch (Exception ex)
{
Repository.UpdateErrorDetails(connectionString,jobId,ex.Message);
}
//Step3 : if step1 and step2 successfull than mark this job as succeeded else failed
// Updating time of whole process in table
}
}
public class Type2 : IBaseType
{
public void LongRunningProcess(int jobId,int noOfTimes)
{
try
{
//Step1 :
var type2Manager = new Type2Manager(params);
for (int i = 0; i < noOfTimes; i++)
{
var con = ConnectionFactory.OpenConnection();
type2Manager.Start(con);
//Save results of those processing
}
//Step2:
IVersioning versioning = new Versioning();
string version = versioning.GetVersion();
using (connection = new SqlConnection(connectionString))
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
try
{
Repository.UpdateVariantVersioning(connection, transaction,jobId, version);
Repository.UpdateCategoryWithVersion(connection, transaction,versioning.Category,version);
transaction.Commit();
}
catch(Exception ex)
{
transaction.Rollback();
//code to delete everything that has been performed in step1
throw ex;
}
}
}
}
catch (Exception ex)
{
Repository.UpdateErrorDetails(connectionString,jobId,ex.Message);
}
//Step3 : if step1 and step2 successfull than mark this job as succeeded else failed
// Updating time of whole process in table
}
}
So as you can see here that step2 and step3 code are getting repeated for both types so I want to this code repetition.
Secondly I want to keep step1 and step2 in sync so that when step2 fails, then rollback whatever has been done inside the entire step1 process.
I am a bit confused with moving versioning in base abstract class because that would probably be tightly coupled with this long running process. I want to design it in a way that tomorrow if I think of removing versioning then it should not hamper my current design and code.
Can anybody please help me with this?
Update : Added versioning code
interface IVersion
{
string CreateVersion();
}
Public class Version : IVersion
{
public string Category { get; private set; }
}