Advertisement
Guest User

Untitled

a guest
Dec 20th, 2016
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.86 KB | None | 0 0
  1. public interface IDbContext : IDisposable
  2. {
  3. IUnitOfWork CreateUnitOfWork();
  4. }
  5.  
  6. public interface IDbContextFactory
  7. {
  8. IDbContext Create();
  9. }
  10.  
  11. public interface IRepositoryFactory
  12. {
  13. T GetRepository<T>(IDbContext context, IUnitOfWork unitOfWork = null)
  14. where T : class;
  15. }
  16.  
  17. public interface IUnitOfWork : IDisposable
  18. {
  19. bool IsInTransaction { get; }
  20. void BeginTransaction();
  21. void BeginTransaction(IsolationLevel isolation);
  22. void CommitTransaction();
  23. void RollbackTransaction();
  24. }
  25.  
  26. public class MysqlDbContext : IDbContext
  27. {
  28. #region Fields
  29. private MySqlConnection _connection;
  30. private bool _disposed;
  31.  
  32. #endregion
  33.  
  34. #region Constructor
  35.  
  36. public MysqlDbContext(MysqlConnectionFactory connectionFactory)
  37. {
  38. //Todo: create and open the connection
  39. _connection = connectionFactory.Create();
  40. if (_connection.State != ConnectionState.Open)
  41. _connection.Open();
  42. }
  43.  
  44. #endregion
  45.  
  46. public MySqlConnection Connection
  47. {
  48. get { return _connection; }
  49. }
  50.  
  51. public IUnitOfWork CreateUnitOfWork()
  52. {
  53. return new MysqlUnitOfWork(_connection);
  54. }
  55.  
  56. public void Dispose()
  57. {
  58. Dispose(true);
  59. }
  60.  
  61. public void Dispose(bool disposing)
  62. {
  63. if (!disposing)
  64. return;
  65.  
  66. /*
  67. * Dispose resources
  68. */
  69. if(_connection != null)
  70. {
  71. Console.WriteLine("Dispose connection!");
  72. _connection.Dispose();
  73. _connection = null;
  74. }
  75.  
  76. //Set disposed
  77. _disposed = true;
  78. }
  79.  
  80.  
  81. }
  82.  
  83. public class MysqlDbContextFactory : IDbContextFactory
  84. {
  85. private MysqlConnectionFactory _connectionFactory;
  86.  
  87. public MysqlDbContextFactory(MysqlConnectionFactory connectionFactory)
  88. {
  89. _connectionFactory = connectionFactory;
  90. }
  91.  
  92. public IDbContext Create()
  93. {
  94. return new MysqlDbContext(_connectionFactory);
  95. }
  96. }
  97.  
  98. public class MysqlRepositoryFactory : IRepositoryFactory
  99. {
  100. #region Constructor
  101.  
  102. public MysqlRepositoryFactory()
  103. {
  104.  
  105. }
  106.  
  107. #endregion
  108.  
  109. public TRepository GetRepository<TRepository>(IDbContext context, IUnitOfWork unitOfWork = null)
  110. where TRepository : class
  111. {
  112. if (typeof(TRepository) == typeof(IUserRepository))
  113. return (new UserRepository(context, unitOfWork)) as TRepository;
  114.  
  115.  
  116. return default(TRepository);
  117. }
  118. }
  119.  
  120. public class MysqlUnitOfWork : IUnitOfWork
  121. {
  122. private readonly MySqlConnection _connection;
  123. private MySqlTransaction _transaction;
  124. private bool _disposed;
  125.  
  126. #region Constructor
  127.  
  128. public MysqlUnitOfWork(MySqlConnection connection)
  129. {
  130. if (connection.State != ConnectionState.Open)
  131. throw new ApplicationException("Cannot begin transaction. Connection is not opened!");
  132.  
  133. _connection = connection;
  134. }
  135.  
  136. #endregion
  137.  
  138. #region Properties
  139.  
  140. public bool IsInTransaction
  141. {
  142. get
  143. {
  144. if (_transaction != null)
  145. return true;
  146.  
  147. return false;
  148. }
  149. }
  150.  
  151. public MySqlTransaction Transaction
  152. {
  153. get
  154. {
  155. return _transaction;
  156. }
  157. }
  158.  
  159. #endregion
  160.  
  161. public void BeginTransaction()
  162. {
  163. BeginTransaction(IsolationLevel.ReadCommitted);
  164. }
  165.  
  166. public void BeginTransaction(IsolationLevel isolation)
  167. {
  168. if (_transaction != null)
  169. throw new ApplicationException("Cannot begin a new transaction while an existing transaction is still running. Please commit or rollback the existing transaction before starting a new one");
  170.  
  171. _transaction = _connection.BeginTransaction(isolation);
  172. }
  173.  
  174. public void CommitTransaction()
  175. {
  176. if (_transaction == null)
  177. throw new ApplicationException("Cannot commit transaction while there is no transaction running");
  178.  
  179. _transaction.Commit();
  180. }
  181.  
  182. public void RollbackTransaction()
  183. {
  184. if (_transaction == null)
  185. throw new ApplicationException("Cannot rollback transaction while there is no transaction running");
  186.  
  187. _transaction.Rollback();
  188. }
  189.  
  190. public void Dispose()
  191. {
  192. Dispose(true);
  193. }
  194.  
  195. public void Dispose(bool disposing)
  196. {
  197. if (!disposing)
  198. return;
  199.  
  200. if(_transaction != null)
  201. {
  202. _transaction.Dispose();
  203. _transaction = null;
  204. }
  205.  
  206. _disposed = true;
  207. }
  208. }
  209.  
  210. public class UserService : IUserService
  211. {
  212. #region Fields
  213.  
  214. private readonly IDbContextFactory _dbContextFactory;
  215. private readonly IRepositoryFactory _repositoryFactory;
  216.  
  217. #endregion
  218.  
  219. #region Constructor
  220.  
  221. public UserService(IDbContextFactory dbContextFactory, IRepositoryFactory repositoryFactory)
  222. {
  223. _dbContextFactory = dbContextFactory;
  224. _repositoryFactory = repositoryFactory;
  225. }
  226.  
  227. #endregion
  228.  
  229. public void Test()
  230. {
  231. using(var context = _dbContextFactory.Create())
  232. {
  233. var userRepository = _repositoryFactory.GetRepository<IUserRepository>(context);
  234.  
  235. userRepository.Create(new User
  236. {
  237. Username = "admin",
  238. Password = "admin",
  239. Email = "admin@bidit.com",
  240. });
  241. }
  242. }
  243.  
  244. public void TestTransaction()
  245. {
  246. using(var context = _dbContextFactory.Create())
  247. {
  248. using(var uow = context.CreateUnitOfWork())
  249. {
  250. var userRepository = _repositoryFactory.GetRepository<IUserRepository>(context, uow);
  251.  
  252. //Begin new transaction (defualt isolation level: ReadCommited)
  253. uow.BeginTransaction();
  254.  
  255. try
  256. {
  257. userRepository.Create(new User
  258. {
  259. Username = "rlydontknow",
  260. Password = "12345",
  261. Email = "rlydontknow@bidit.com",
  262. });
  263.  
  264. //Commit transaction
  265. uow.CommitTransaction();
  266. }
  267. catch
  268. {
  269. //Rollback transaction on error
  270. uow.RollbackTransaction();
  271. throw;
  272. }
  273.  
  274. }
  275. }
  276. }
  277. }
  278.  
  279. public interface IDbContext : IDisposable
  280. {
  281. IUnitOfWork CreateUnitOfWork();
  282. }
  283.  
  284. public interface IUnitOfWork : IDisposable
  285. {
  286. void Commit();
  287. void Rollback();
  288. }
  289.  
  290. public interface IConnectionFactory
  291. {
  292. IDbConnection Create();
  293. }
  294.  
  295. public class MysqlConnectionFactory : IConnectionFactory
  296. {
  297. private string _connectionString;
  298.  
  299. public MysqlConnectionFactory(string connectionString)
  300. {
  301. _connectionString = connectionString;
  302. }
  303.  
  304. public string ConnectionString
  305. {
  306. get
  307. {
  308. return _connectionString;
  309. }
  310. }
  311.  
  312.  
  313. public IDbConnection Create()
  314. {
  315. var connection = new MySqlConnection(_connectionString);
  316. connection.Open();
  317.  
  318. return connection;
  319. }
  320. }
  321.  
  322. public class MysqlDbContext : IDbContext
  323. {
  324. private IDbConnection _connection;
  325. private MysqlUnitOfWork _currentUnitOfWork;
  326.  
  327. public MysqlDbContext(IConnectionFactory connectionFactory)
  328. {
  329. //Create new connection
  330. _connection = connectionFactory.Create();
  331. if (_connection.State != ConnectionState.Open)
  332. _connection.Open();
  333. }
  334.  
  335. public IDbConnection Connection
  336. {
  337. get
  338. {
  339. return _connection;
  340. }
  341. }
  342.  
  343. public MysqlUnitOfWork CurrentUnitOfWork
  344. {
  345. get
  346. {
  347. return _currentUnitOfWork;
  348. }
  349. }
  350.  
  351.  
  352. public IUnitOfWork CreateUnitOfWork()
  353. {
  354. if (_currentUnitOfWork != null)
  355. throw new InvalidOperationException("Cannot create new unit of work. Commit or rollback current one.");
  356.  
  357. _currentUnitOfWork = new MysqlUnitOfWork(_connection);
  358.  
  359. return _currentUnitOfWork;
  360. }
  361.  
  362. public void Dispose()
  363. {
  364. Dispose(true);
  365. }
  366.  
  367. public void Dispose(bool disposing)
  368. {
  369. if (!disposing)
  370. return;
  371.  
  372. if(_connection != null)
  373. {
  374. _connection.Dispose();
  375. _connection = null;
  376. }
  377. }
  378. }
  379.  
  380. public abstract class MysqlRepository
  381. {
  382. private readonly MysqlDbContext _context;
  383.  
  384. public MysqlRepository(IDbContext context)
  385. {
  386. if (context.GetType() != typeof(MysqlDbContext))
  387. throw new InvalidOperationException("Incorrect context type. MysqlDbContext required!");
  388.  
  389. _context = (MysqlDbContext)context;
  390. }
  391.  
  392. public MysqlDbContext Context
  393. {
  394. get
  395. {
  396. return _context;
  397. }
  398. }
  399.  
  400. protected IDbConnection Connection
  401. {
  402. get
  403. {
  404. if (_context != null)
  405. return _context.Connection;
  406.  
  407. return null;
  408. }
  409. }
  410.  
  411. protected IDbTransaction Transaction
  412. {
  413. get
  414. {
  415. if (_context != null && _context.CurrentUnitOfWork != null)
  416. return _context.CurrentUnitOfWork.Transaction;
  417.  
  418. return null;
  419. }
  420. }
  421. }
  422.  
  423. public class MysqlUnitOfWork : IUnitOfWork
  424. {
  425. private IDbTransaction _transaction;
  426. private bool _commited;
  427.  
  428. public MysqlUnitOfWork(IDbConnection connection, IsolationLevel isolation = IsolationLevel.ReadCommitted)
  429. {
  430. if (connection == null)
  431. throw new ArgumentNullException("connection");
  432.  
  433. if (connection.State != ConnectionState.Open)
  434. throw new InvalidOperationException("Cannot create unit of work. Connection to the database is not estabilished!");
  435.  
  436. //Begin new transaction
  437. _transaction = connection.BeginTransaction(isolation);
  438.  
  439. }
  440.  
  441. public IDbTransaction Transaction
  442. {
  443. get
  444. {
  445. return _transaction;
  446. }
  447. }
  448.  
  449. public void Commit()
  450. {
  451. if (_transaction == null)
  452. throw new InvalidOperationException("Cannot commit transaction while there is no transaction running");
  453.  
  454. _transaction.Commit();
  455.  
  456. _commited = true;
  457. }
  458.  
  459. public void Rollback()
  460. {
  461. if (_transaction == null)
  462. throw new InvalidOperationException("Cannot rollback transaction while there is no transaction running");
  463.  
  464. if (_commited)
  465. throw new InvalidOperationException("Cannot rollback already commited transaction");
  466.  
  467. _transaction.Rollback();
  468. }
  469.  
  470. public void Dispose()
  471. {
  472. Dispose(true);
  473. }
  474.  
  475. public void Dispose(bool disposing)
  476. {
  477. if (!disposing)
  478. return;
  479.  
  480. if(_transaction != null)
  481. {
  482. //Automatically rollback if not commited
  483. if (!_commited)
  484. _transaction.Rollback();
  485.  
  486. _transaction.Dispose();
  487. _transaction = null;
  488. }
  489.  
  490. }
  491.  
  492.  
  493. }
  494.  
  495. public class UserRepository : MysqlRepository, IUserRepository
  496. {
  497. public UserRepository(IDbContext context)
  498. : base(context)
  499. {
  500.  
  501. }
  502.  
  503. public void Create(User user)
  504. {
  505. var parameters = new
  506. {
  507. username = user.Username,
  508. password = user.Password,
  509. email = user.Email,
  510. };
  511.  
  512. user.Id = (uint)Connection.Query<ulong>("INSERT INTO users (username, password, email) VALUES (@username, @password, @email); select last_insert_id();", parameters).First();
  513. }
  514. }
  515.  
  516. public class UserService : IUserService
  517. {
  518. private readonly IUserRepository _userRepository;
  519.  
  520. public UserService(IUserRepository userRepository)
  521. {
  522. _userRepository = userRepository;
  523. }
  524.  
  525.  
  526.  
  527. public void Create()
  528. {
  529. var user = new User
  530. {
  531. Username = "rlydontknow",
  532. Password = "12345",
  533. Email = "rlydontknow@sharpbid.com"
  534. };
  535.  
  536. _userRepository.Create(user);
  537.  
  538. Console.WriteLine("New user created! User id: " + user.Id);
  539.  
  540. }
  541. }
  542.  
  543. class Program
  544. {
  545. private static IConnectionFactory _connectionFactory;
  546.  
  547. static void Main(string[] args)
  548. {
  549. _connectionFactory = new MysqlConnectionFactory("Server=localhost;Database=sharpbid;Uid=root;Pwd=maniek1;");
  550.  
  551.  
  552. SomeLogicalOperation();
  553.  
  554. Console.ReadLine();
  555. }
  556.  
  557. static void SomeLogicalOperation()
  558. {
  559. using(var context = GetContext())
  560. {
  561. var userRepository = new UserRepository(context);
  562.  
  563. /*
  564. * Do some stuff without transaction
  565. */
  566.  
  567. //Begin transaction
  568. using (var uow = context.CreateUnitOfWork())
  569. {
  570. var userService = new UserService(userRepository);
  571.  
  572. userService.Create();
  573.  
  574. //Commit transaction
  575. uow.Commit();
  576. }
  577. }
  578. }
  579.  
  580. static IDbContext GetContext()
  581. {
  582. return new MysqlDbContext(_connectionFactory);
  583. }
  584. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement