Transition from Entityspaces(Tiraggo) into Servicestack Ormlite - repository

at this moment we are migrating from Entityspaces(Tiraggo) into Servicestack Ormlite.
One point is the way to open and close the DBConnection.
I apologize for the comparission but it is useful for the question. In Tiraggo, inside my wep application, in the global.asax.cs I put this:
protected void Application_Start(object sender, EventArgs e)
{
Tiraggo.Interfaces.tgProviderFactory.Factory = new Tiraggo.Loader.tgDataProviderFactory();
}
In web.config exists the section for Tiraggo, the connectionstring and the ORM does the rest.
During the use of the classes we just do this:
User user = new User(); user.Name="some"; user.Comment = "some"; user.Save();
I dont open, close a DBConnection. It is transparent for the programmer. Just create the instance classes and use them.
I define a class, a repository and that's all. No DB definition or interaction. Everything happens in a webforms app, with the datalayer inside the same app.
When we are migrating to Servicestack ORMLite, I see the open of the DBConnection is too inside the globlal.asax.cs, but it references a Service no a class or repository.
public class AppHost : AppHostBase
{
public AppHost() : base("Hello ServiceStack", typeof(HelloService).Assembly) {}
public override void Configure(Container container) {}
}
So my first question is: how can I use it if I dont have a Service (HelloService), I have just classes or repositories. So I cant use this technique for DBConnection my DB.
I also see that accesing the Db, I need a open connection. I try to do this:
using (var Db = DbFactory.Conn.OpenDbConnection())
{
return Db.SingleById<Anio>(id);
}
Later, I found a sample like I was looking for, the Pluralsight video ".NET Micro ORMs" Steve Mihcelotti, and he just open the connection, but never Close it, never use the "using" syntax.
So my 2 questions are:
1) Is there a way for open the DbFactory(dbConnection) like all the samples using servicestack ormlite, but without using a Services ( I dont use Services, I want to use Ormlite but just with classes and repositories)
2) Is there a way for connnect to the database in each trip to the class or repository without using the "using" syntax, or
3) the only way is the one showed in the Pluralsight video, ie. open the connection throw the using syntax in each Method (trip to the class)
I hope I was clear.

The nice thing about IDbConnectionFactory is that it's a ThreadSafe Singleton which can be safely passed around and referenced as it doesn't hold any resources open itself (i.e. DB Connections).
A lazy pattern which provides a nice call-site API is the RepositoryBase class:
public abstract class RepositoryBase : IDisposable, IRepository
{
public virtual IDbConnectionFactory DbFactory { get; set; }
IDbConnection db;
public virtual IDbConnection Db
{
get { return db ?? (db = DbFactory.OpenDbConnection()); }
}
public virtual void Dispose()
{
if (db != null)
db.Dispose();
}
}
This is the same pattern ServiceStack's Service class uses to provide a nice API that only gets opened when it's used in Services, e.g:
public class MyRepository : RepositoryBase
{
public Foo GetFooById(int id)
{
return Db.SingleById<Foo>(id);
}
}
Note: This pattern does expect that your dependencies will be disposed after use.
Another alternative is to leverage your IOC to inject an Open IDbConnection with a managed lifetime scope, e.g:
container.Register<IDbConnection>(c =>
c.Resolve<IDbConnectionFactory>().OpenDbConnection())
.ReusedWithin(ReuseScope.Request);
The life-cycle of the connection is then up to your preferred IOC.
Without Using an IOC
Whilst it's typically good practice to use an IOC to manage your Apps dependencies and provide loose-coupling, if you don't want to use an IOC you can also make DbFactory a static property, e.g:
public abstract class RepositoryBase : IDisposable
{
public static IDbConnectionFactory DbFactory { get; set; }
IDbConnection db;
public virtual IDbConnection Db
{
get { return db ?? (db = DbFactory.OpenDbConnection()); }
}
public virtual void Dispose()
{
if (db != null)
db.Dispose();
}
}
Which you can just initialize directly on startup, e.g:
protected void Application_Start(object sender, EventArgs e)
{
RepositoryBase.DbFactory = new OrmLiteConnectionFactory(
connectionString, SqlServer.Provider);
}
Note: If you're not using an IOC then you want to make sure that instances of your repository classes (e.g. MyRepository) are disposed of after use.

Related

Connection String retrieved from one DB to be used in a Class Library to access a 2nd DB...Suggestions?

Environment:
.Net, SQL Server, WinForms Desktop
Control Database (db1)
Customer Databases (db2, db3, db4, etc.)
Background:
Each of our customers requires their own database. It's a contractual obligation due to compliance with standards in certain industries. Certain users of our application only have access to specific databases.
Scenario:
The application user's username gets passed into our control database (db1) from the app on load. There's a lookup in there that determines what customer this user has access to and returns connection string info for connecting to the database of the determined customer (db2 or db3 or db4 or etc.) to be used for the life of the runtime. All of my business logic is in a DAL, as it should be, in a .Net class library.
Suggestions on the best way/ways to get the connection string information into the DAL WITHOUT passing into every constructor/method that is called on the DAL.
I came up with one possible solution, but want to pick your brains to see if there's another or better way.
Possible Solutions:
A Global module in the DAL that has public fields like "dbServer" and "dbName".
Set those and then use the DAL as needed. They would need to be set each time the DAL is used throughout the application, but at least I don't have to make the signature of every single constructor and method require connection string information.
A settings file (preferably XML) that the app writes to after getting the connection info and the DAL reads from for the life of the runtime.
Thoughts and/or suggestions? Thanks in advance.
A set up like this might help. If you are going the IoC way, then you can remove the parameterized constructor and make Connection object a dependency too. However, you will need to feed your dependency injection provider in code since connection string comes from database.
public class User
{
public string ConnectionString
{
get; set;
}
}
public class SomeBusinessEntity
{
}
public class CallerClass
{
public IBaseDataAccess<SomeBusinessEntity> DataAccess
{
get;
set;
}
public void DoSomethingWithDatabase(User user)// Or any other way to access current user
{
// Either have specific data access initialized
SpecificDataAccess<SomeBusinessEntity> specificDataAccess = new SpecificDataAccess<SomeBusinessEntity>(user.ConnectionString);
// continue
// have dependency injection here as well. Your IoC configuration must ensure that it does not kick in until we get user object
DataAccess.SomeMethod();
}
}
public interface IBaseDataAccess<T>
{
IDbConnection Connection
{
get;
}
void SomeMethod();
// Other common stuff
}
public abstract class BaseDataAccess<T> : IBaseDataAccess<T>
{
private string _connectionString;
public BaseDataAccess(string connectionString)
{
_connectionString = connectionString;
}
public virtual IDbConnection Connection
{
get
{
return new SqlConnection(_connectionString);
}
}
public abstract void SomeMethod();
// Other common stuff
}
public class SpecificDataAccess<T> : BaseDataAccess<T>
{
public SpecificDataAccess(string connectionString) : base(connectionString)
{
}
public override void SomeMethod()
{
throw new NotImplementedException();
}
public void SomeSpecificMethod()
{
using (Connection)
{
// Do something here
}
}
}
Create a ConnectionStringProvider class that will provide you the connection string
public class ConnectionStringProvider
{
// store it statically so that every instance of connectionstringprovider
// uses the same value
private static string _customerConnectionString;
public string GetCustomerConnectionString()
{
return _customerConnectionString;
}
public void SetCustomerConnectionString(string connectionString)
{
_customerConnectionString = connectionString;
}
}
Using ConnectionStringProvider in your DAL
public class MyCustomerDAL
{
private ConnectionStringProvider _connectionStringProvider;
public MyCustomerDAL()
{
_connectionStringProvider = new ConnectionStringProvider();
}
public void UpdateSomeData(object data)
{
using (var con = new SqlConnection(
connectionString: _connectionStringProvider.GetCustomerConnectionString()))
{
//do something awesome with the connection and data
}
}
}
Setting/changing the connection string
new ConnectionStringProvider()
.SetCustomerConnectionString(connString);
Note
The reason i chose to use method instead of a get/set property in ConnectionStringProvider is because maybe in the future you decide to read/write these from a file, and while you could read/write from file in a property it's misleading to your consumer who thinks that a property will be a simple performance-less hit.
Using a function tells your consumer there might be some performance hit here, so use it wisely.
A little abstration for unit testing
Here is a slight variation that will enable you to abstract for unit testing (and eventually IoC)
public class MyCustomerDAL
{
private IConnectionStringProvider _connectionStringProvider;
public MyCustomerDAL()
{
//since not using IoC, here you have to explicitly new it up
_connectionStringProvider = new ConnectionStringProvider();
}
//i know you don't want constructor, i included this to demonstrate how you'd override for writing tests
public MyCustomerDAL(IConnectionStringProvider connectionStringProvider)
{
_connectionStringProvider = connectionStringProvider;
}
public void UpdateSomeData(object data)
{
using (var con = new SqlConnection(
connectionString: _connectionStringProvider.GetCustomerConnectionString()))
{
//do something awesome with the connection and data
}
}
}
// this interface lives either in a separate abstraction/contracts library
// or it could live inside of you DAL library
public interface IConnectionStringProvider
{
string GetCustomerConnectionString();
void SetCustomerConnectionString(string connectionString);
}
public class ConnectionStringProvider : IConnectionStringProvider
{
// store it statically so that every instance of connectionstringprovider uses the same value
private static string _customerConnectionString;
public string GetCustomerConnectionString()
{
return _customerConnectionString;
}
public void SetCustomerConnectionString(string connectionString)
{
_customerConnectionString = connectionString;
}
}
Appendix A - Using IoC and DI
Disclaimer: the goal of this next piece about IoC is not to say one way is right or wrong, it's merely to bring up the idea as another way to approach solving the problem.
For this particular situation Dependency Injection would make your solving the problem super simple; specifically if you were using an IoC container combined with constructor injection.
I don't mean it would make the code more simple, that would be more or less the same, it would make the mental side of "how do I easily get some service into every DAL class?" an easy answer; inject it.
I know you said you don't want to change the constructor. That's cool, you don't want to change it because it is a pain to change all the places of instantiation.
However, if everything were being created by IoC, you would not care about adding to constructors because you would never invoke them directly.
Then, you could add services like your new IConnectionStringProvider right to the constructor and be done with it.

Repository pattern dependency injection using Dapper

My Startup.cs contains 40 repositories:
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IXRepository, XRepository>();
... 40 more lines ...
I'm trying to find a way to have this mess in a single line, but I'm failing miserably to put my head around this, I have several methods that are not available in the interface. Can someone provide some help? I understand why it is not working, it does not have a concrete repository, but I'm no closer to making this work.
InvalidOperationException: Unable to resolve service for type...
// IRepository.cs
public interface IRepository
{
}
// IUserRepository.cs
public interface IUserRepository : IRepository
{
User ReadToken(string email, string password);
}
// BaseRepository.cs
public class BaseRepository : IDisposable
{
protected IDbConnection PostgreSQL;
public BaseRepository(IDbConnection postgreSQL)
{
PostgreSQL = postgreSQL;
}
public void Dispose()
{
}
}
// UserRepository.cs
public class UserRepository : BaseRepository, IUserRepository
{
public UserRepository(IDbConnection postgreSQL) : base(postgreSQL)
{
}
public User ReadToken(string email, string password)
{
object parameters;
string sql;
parameters = new
{
email,
password
};
sql =
#"
SELECT
user_id AS id,
token
FROM users
WHERE
email = #email AND
password = CRYPT(#password, password) AND
active = TRUE;
";
var user = base.PostgreSQL.Query<User>(sql, parameters).SingleOrDefault();
if (user == null)
throw new UnauthorizedException("User", "User not found.");
return user;
}
}
// UsersController.cs
public class UsersController : ControllerBase
{
protected IUserRepository UserRepository;
public UsersController(IUserRepository userRepository)
{
UserRepository = userRepository;
}
}
// Startup.cs
services.AddTransient<IRepository, BaseRepository>();
You can do that with Scrutor
It offers assembly scanning and decoration extensions for Microsoft.Extensions.DependencyInjection
All those repositories can be summed up to something like this:
services.Scan(x => x.FromAssemblyOf<IAnAssemblyRegistrationMarker>()
.AddClasses(filter => filter.AssignableTo(typeof(IRepository)))
.AsImplementedInterfaces()
.WithScopedLifetime());
IAnAssemblyRegistrationMarker is an empty interface to point at the assembly (project) you want to scan
AddClasses Adds all public, non-abstract classes from the selected assemblies that matches the requirements specified in the
AsImplementedInterfaces Registers each matching concrete type as all of its implemented interfaces
WithScopedLifetime Registers each matching concrete type with Scoped Lifetime (You also have WithSingletonLifetime and WithTransientLifetime)
The only requirement in the code example above is that the repositories implement IRepository in order for you to target only the necessary items.
Disclaimer: I am not associated with Scrutor in any way. I just like the thing.
What you are looking for is called convention based registration. This gives you ability register all types which for example ends with Repository as the interfaces they implement. However the built-in ASP.NET Core IOC is very lightweight and doesn't provide such functionality. So you can either wrap it up with your code which scans all referenced assemblies, look for types by a pattern and then add them to ServiceCollection or you can use different IOC implementation that provides this functionality and supports .Net Core e.g. Autofac, StructureMap etc.

How to add db context not in ConfigureServices method ASP.NET Core

Is there any posibility to add a db context in external class/method "on fly?" When I run the application, there is no any connection string, so I need to generate a db after typing some information(server, dbname, ect)
One way is to use the factory pattern, i.e. creating a service that will be used to create new instances of your context.
Here is an example, it is not a final solution and you will need to adapt it to your needs but it should give you an idea of the technique:
public interface IDbContextFactory
{
DbContext CreateDbContext(string connectionString);
}
public class DbContextFactory : IDbContextFactory
{
public DbContext CreateDbContext(string connectionString)
{
return new DbContext(connectionString);
}
}
Then in asp.net core, you can register the context factory and inject it in your controller:
services.AddSingleton<IDbContextFactory, DbContextFactory>();
public class SomeController
{
private IDbContextFactory contextFactory;
public SomeController(IDbContextFactory contextFactory)
{
this.contextFactory = contextFactory;
}
public IActionResult Index()
{
using(var db = contextFactory.CreateDbContext("Your connection string")) {
//Get some data
}
return View();
}
}
Instead of creating a DbContext you could combine the factory pattern with the unit of work and / or repository patterns to better separate concerns and to make sure you always dispose the context, etc...
Use new YourContext(new DbContextOptionsBuilder<YourContext>().Use...().Options)

Calling WCF service with parameter

I am developing a SharePoint addin which has a SharePoint-hosted part and a provider-hosted part. In my provider hosted part, I have a couple of services that install a couple of things like Taxonomy and Search. I use C# CSOM for this. This is the only purpose of the provider-hosted part. When the addin is installed, a AppInstalled Event Triggers which calls a remote event receiver. This remote event receiver should then call my WCF services one by one.
Now to my actual question: I currently use this approach for consuming my services:
var taxBinding = new BasicHttpBinding();
var taxEndpoint = new EndpointAddress(remoteUrl.ToString() + "/Services/TaxonomySetupService.svc");
var taxChannelFactory = new ChannelFactory<ISetupService>(taxBinding, taxEndpoint);
ISetupService taxClient = null;
try
{
taxClient = taxChannelFactory.CreateChannel();
taxClient.SetAppWebUrl(appWebUrl.ToString());
if (!taxClient.IsInstalled())
taxClient.Install();
string logs = taxClient.GetLogs();
((ICommunicationObject)taxClient).Close();
}
catch (Exception ex)
{
if (taxClient != null)
{
((ICommunicationObject)taxClient).Abort();
}
}
ISetupService:
[ServiceContract]
public interface ISetupService
{
string OpenText { get; }
string DoneText { get; }
string AppWebUrl { get; set; }
[OperationContract]
bool IsInstalled();
[OperationContract]
void SetLogComponent(LogList logList);
[OperationContract]
void SetAppWebUrl(string url);
[OperationContract]
void WriteToLog(string message);
[OperationContract]
string GetLogs();
[OperationContract]
void Install();
}
My solution doesn't have to follow this approach though so I am looking for something better. Specifically, I need to pass a ClientContext object into my ISetupService constructor. What would be the simplest approach here?
Option 1 - Lazy Injectable property
Why in the constructor? Why not have a Lazy Injectable property?
internal IClientContext Context
{
get { return _Context ?? (_Context = SomeStaticHelper.Context); }
set { _Context = value; } // Allows for replacing IContext for unit tests
} private IClientContext _Context;
public class SomeStaticHelper
{
public static IContext Context { get; set; } // Set this in global.asax
}
Pro: No additional library
Pro: Your can replace IContext in Unit Tests easily (use InternalsVisibleTo)
Con: Class is coupled to SomeStaticHelper for compile.
Con: Doing this for one class is nice, but doing this for 100 classes is not so nice.
Option 2 - Dependency Injection
Or you could use straight up dependency injection, such as Autofac.
http://docs.autofac.org/en/latest/getting-started/
Pro: The class is decoupled and the dependency is injected.
Pro: If you have many classes that need dependency injection, this is the way to go because the overhead is now a couple class files instead of a property in every class file.
Con: You have to add a framework to your code.
Con: You now need more code and other objects to configure the dependency injection.
Use option 1 for small projects that have little need for dependency injection. I think this is the simplest approach here.
Use option 2 for large projects that use DI all the time.

Entity Framework 5 - How to change connection string for unit testing?

This is my first foray into Entity Framework, and I have a working project with EF5 and the repository pattern. I want to do integration testing against a live DB. I made a snapshot of my existing production database and wrote a stored procedure to recreate a fresh snapshot every time I want to run tests. My question is how to I switch my context to this database snapshot when "in unit testing mode"? In my app.config I have both my live and test connection strings as such:
<connectionStrings>
<add name="ReportingDbContext" connectionString="Server=LiveServer;Database=UnifiedReporting;User Id='myuser';Password='mypass';Trusted_Connection=False" providerName="System.Data.SqlClient" />
<add name="TestingDbContext" connectionString="Server=LiveServer;Database=UnifiedReportingSnapshot;User Id='myuser';Password='mypass';Trusted_Connection=False" providerName="System.Data.SqlClient" />
</connectionStrings>
As it stands now, I have my DbContext with the entities I want to use as follows:
public class ReportingDbContext : DbContext
{
public ReportingDbContext() : base("name=ReportingDbContext") // as per my app.config
{
}
// inventory
public DbSet<ComputerEntity> Computers { get; set; }
public DbSet<NetworkAdapterEntity> NetworkAdapters { get; set; }
// ... plus a whole bunch more
}
What I think I need to do is change the base("name=ReportingDbContext") into ("name=TestingDbContext"), but given how I have my Repository/UnitOfWork setup I'm not seeing how I can do so. The issue may be here in my UnitOfWork:
public interface IUnitOfWork : IDisposable
{
void Commit();
// inventory
IRepository<ComputerEntity> Computers { get; }
IRepository<NetworkAdapterEntity> NetworkAdapters { get; }
// ... plus a bunch more
}
public class UnitOfWork : IUnitOfWork
{
private readonly ReportingDbContext _dbContext = null;
public UnitOfWork()
{
_dbContext = new ReportingDbContext();
}
public void Commit()
{
_dbContext.SaveChanges();
}
// Inventory
public IRepository<ComputerEntity> Computers {get { return new Repository<ComputerEntity>(_dbContext); }}
public IRepository<NetworkAdapterEntity> NetworkAdapters { get { return new Repository<NetworkAdapterEntity>(_dbContext); } }
// ... lots more
}
This UnitOfWork has been great is that I can do a bunch of stuff to all my repositories and save it in one shot without having a bunch of contexts floating around to synchronize. It may or may not be relevant to this question, but this is how my UnitOfWork uses the repository. There is only 1 repository class, but it can be fed with any entity type needed:
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
IQueryable<T> Find(Expression<Func<T, bool>> predicate);
T GetById(int id);
void Remove(T entity);
void Add(T newEntity);
}
public class Repository<T> : IRepository<T> where T : class
{
protected DbContext DbContext { get; set; }
protected DbSet<T> DbSet { get; set; }
public Repository(DbContext dbContext)
{
if (dbContext == null)
{
throw new ArgumentNullException("dbContext");
}
DbContext = dbContext;
DbSet = DbContext.Set<T>();
}
public IQueryable<T> GetAll()
{
return DbSet;
}
// ... more implementation of the interface, nothing fancy
}
The endpoint of where this magic is used is inside my WCF service. This is where I want to actually run through an integration test. A particular method in my service initializes a unit of work and uses that do stuff. The UnitOfWork creates a ReportingDbContext when it is new'd up, and this ReportingDbContext in turn refers to the connection string of "name=ReportingDbContext". After much reading, I think the answer is to use an IoC container like Unity or Ninject (haven't used one before, but I'd like to), and I'm stuck on how to implement IoC in this situation. Here is an example method that I'm using in my WCF service that seems rather hardcoded to the live database connection string:
public ComputerDTO GetComputerDetails(string hostname, string client)
{
// don't worry about the return type, it's defined elsewhere
using (var uoW = new UnitOfWork())
{
var repo = uoW.Computers;
var computer = repo.Find(x => x.Hostname == hostname && x.CompanyEntity.Name == client).FirstOrDefault();
// do stuff
}
}
I'd like to keep my connection strings inside my app.config if at all possible and be able to somehow switch to the testing connection string during the [SetUp] part of my NUnit testing of the methods in my WCF service.
I alway s use a separate unit test project with an App.config of its own. The connection string has the same name as in the main app but the database connection is different.
When you run unit test, e.g. from within Visual Studio, in the background a unit test runner is executed that is nothing but a regular application with its own configuration, the app.config.
You can start and dispose contexts for each test. Most unit test frameworks have attributes to mark methods as setup/teardown fixtures that can either run per test fixture or per test. You could initialize an IoC container in a test fixture setup ([TestFixtureSetUp] in NUnit) and a context in a test setup ([SetUp] in NUnit).
For some scenarios we use scripts to ensure and restore database state, but for most test we start a TransactionScope in the test setup and dispose it (without committing) in the test teardown. This conveniently rolls back any changes made in the test, but the database changes made in the tests are for real.