I am working on a test suit implementation which uses the SpecFlow + SpecRunner and XUnit. and we are trying to do parallel test execution and i would like to know is there are a way that i can run a hook in the begining of the test run and store the token value in a static variable so that that can be shared among threads.
to summarize is there a way that specflow offers a mechanism to share data between threads during parallel execution.
We can share the data using any one of the below approach
Scenario Context
Context Injection
Here, Approach 1 and 2 will not have any issue in multiple thread. Since, Context Injection life is specific to the scenario Level.
Approach 1 : we can define the Token Generation Step within the BeforeScenario hooks and the generated Token values can be updated in the ScenarioContext.
we can directly access the token from the scenario context in any place like below
Here, Token will be generated before each scenario run and it will not affect the Parallel execution.For more Details, Parallel-Execution
Scenarios and their related hooks (Before/After scenario, scenario block, step) are isolated in the different threads during execution and do not block each other. Each thread has a separate (and isolated) ScenarioContext.
Hooks Class:
public class CommonHooks
{
[BeforeScenario]
public static void Setup()
{
// Add Token Generation Step
var adminToken = "<Generated Token>";
ScenarioContext.Current["Token"] = adminToken;
}
}
Step Class:
[Given(#"I Get the customer details""(.*)""")]
public void WhenIGetTheCustomerDetails(string endpoint)
{
if(ScenarioContext.Current.ContainsKey("Token"))
{
var token = ScenarioContext.Current["Token"].ToString();
//Now the Token variable holds the token value from the scenario context and It can be used in the subsequent steps
}
else
{
Assert.Fail("Unable to get the Token from the Scenario Context");
}
}
If you wish to share the same token across multiple Step, then you can assign this token value within constructor and it can be used
For Example,
[Binding]
public class CustomerManagementSteps
{
public readonly string token;
public CustomerManagementSteps()
{
token= ScenarioContext.Current["Token"].ToString();
}
[Given(#"I Get the customer details""(.*)""")]
public void WhenIGetTheCustomerDetails(string endpoint)
{
//Now the Token variable holds the token value from the scenario context and It can be used in the subsequent steps
}
}
Approach 2: Context Injection details can be referred in the below link with an example
Context Injection
Updated
Given the downvote and comments, I've updated my code example to better show exactly one way you can use dependency injection here with code of your own design. This shared data will last the lifetime of the scenario and be used by all bindings. I think that's what you're looking for unless I'm mistaken.
//Stores whatever data you want to share
//Write this however you want, it's your code
//You can use more than one of these custom data classes of course
public class SomeCustomDataStructure
{
//If this is run in paralell, this should be thread-safe. Using List<T> for simplicity purposes
//Use EF, ConcurrentCollections, synchronization (like lock), etc...
//Again, do NOT copy this code for parallel uses as List<int> is NOT thread-safe
//You can force things to not run in parallel so this can be useful by itself
public List<int> SomeData { get; } = new List<int>();
}
//Will be injected and the shared instance between any number of bindings.
//Lifespan is that of a scenario.
public class CatalogContext : IDisposable
{
public SomeCustomDataStructure CustomData { get; private set; }
public CatalogContext()
{
//Init shared data however you want here
CustomData = new SomeCustomDataStructure();
}
//Added to show Dispose WILL be called at the end of a scenario
//Feel free to do cleanup here if necessary.
//You do NOT have to implement IDiposable, but it's supported and called.
public void Dispose()
{
//Below obviously not thread-safe as mentioned earlier.
//Simple example is all.
CustomData.SomeData.Clear();
}
}
[Binding]
public class SomeSteps
{
//Data shared here via instane variable, accessable to multiple steps
private readonly CatalogContext catalogContext;
//Dependency injection handled automatically here.
//Will get the same instance between other bindings.
public SomeSteps(CatalogContext catalogContext)
{
this.catalogContext = catalogContext;
}
[Given(#"the following ints")]
public void GivenTheFollowingInts(int[] numbers)
{
//This will be visible to all other steps in this binding,
//and all other bindings sharing the context
catalogContext.CustomData.SomeData.AddRange(numbers);
}
}
Related
ASP.NET MVC 5 Project.
I know that the best practice of using EF context object as the following
using(var context = new ContextDB())
{
}
But I am working with a large existing project which not used this practice.
the project using the following pattern
public abstract class BaseService
{
private static ContextDB _data { get; set; }
public static ContextDB Data
{
get
{
if (_data== null)
_data= new ContextDB();
return _data;
}
}
}
Actually, because of this pattern, I am receiving this exception (sometimes, not always)
So to solve this I have to change all the code which is using the shared Data
property and replace it with the new instance of ContextDB as I mentioned in the beginning of the question.
The problem that this is a very large modification, and I will not be allowed to do that modification.
The Question, can I solve this problem without changing a ton of code, In another word, can I solve the problems with modifications done only inside the BaseService class, for example, Is there any event which I could handle to know if any query is executed and then dispose of the ContextDB
here is the pseudo-code of the idea in my mind
public abstract class BaseService
{
public static ContextDB Data
{
get
{
ContextDB _data= new ContextDB();
_data.SqlQueryExecuted += () => { this._data.dispose(); }
return _data;
}
}
}
NOTE: the SaveChanged event is not suitable, because not all of the query are updating or inserting.
I may use following solution.
In Global.asax
Begin Request : Create Instance of your dbContext. Store it in HttpContext.Current.Items.
End Request : Grab the context and close / dispose connection.
Another better solution is to use DI. Dependency Injection and limit the scope of your instance. There are many way Like Singleton, PerRequest etc.
I'm working on an application using an Ignite.Net cache infront of an Oracle database.
I read that I can write to multiple caches at once safely using Ignite Transactions (https://apacheignite-net.readme.io/v1.5/docs/transactions#Cross-cache transactions).
I also read that each cache can have it's own CacheStore that writes to the underlying database but I've yet to find any documentation that explains how I should implement the CacheStore classes so the database writes are safe across the whole Ignite transaction.
I've seen information on SessionEnd and CacheStoreSession (https://apacheignite-net.readme.io/v2.6/docs/persistent-store#section-sessionend-) but these don't mention multiple CacheStores.
The following article explains how transactions are handled for 3rd party persistence but this again only talks of a single Cache/CacheStore (https://www.gridgain.com/resources/blog/apache-ignite-transactions-architecture-transaction-handling-level-3rd-party)
Can anyone advise how this works (assuming it does) or point me to further examples/documentation?
For a definitive answer (appreciate your time #alamar), I've spoken with one of the nice people at Gridgain and can confirm it is possible to safely perform transactions across multiple CacheStores, where all stores write to the same database without data inconsistency. It's not done via a mechanism specifically coded into Ignite as I had wondered about but can be implemented safely via a simple shared database connection.
For this to work you need to:
Make your caches transactional (AtomicityMode = CacheAtomicityMode.Transactional, WriteThrough = true)
Share a single database connection between the data stores (either inject via the CacheStoreFactory or use a singleton)
In all write operations on the CacheStores, write to the shared session database but do not commit. Mark the session as requiring a commit (your own boolean flag).
Implement SessionEnd (https://apacheignite-net.readme.io/docs/persistent-store#section-sessionend-) in each of your CacheStores. The implementation should call commit on your shared database connection if it has not already been called (check the boolean flag from the step before and reset after commit). You could always encapsulate that logic in your database connection class.
A simplified code example:
public class SharedDatabaseSession
{
private bool commitRequired;
private DatabaseConnection databaseConnection;
// ....
public void Write( /*xyz*/)
{
databaseConnection.Write( /*xyz*/);
commitRequired = true;
}
public void Commit()
{
if (commitRequired)
{
databaseConnection.Commit();
commitRequired = false;
}
}
public static SharedDatabaseSession GetInstance()
{
return instance;
}
}
public class FirstCacheStore : CacheStoreAdapter<int, int>
{
private SharedDatabaseSession database = SharedDatabaseSession.GetInstance();
/// ......
public override void Write(int key, int val)
{
database.Write( /*xyz*/);
}
public override void SessionEnd(bool commit)
{
if (commit)
{
database.Commit();
}
}
}
public class SecondCacheStore : CacheStoreAdapter<int, int>
{
private SharedDatabaseSession database = SharedDatabaseSession.GetInstance();
/// ......
public override void Write(int key, int val)
{
database.Write( /*xyz*/);
}
public override void SessionEnd(bool commit)
{
if (commit)
{
database.Commit();
}
}
}
Have you tried it?
My expectation, it should technically be supported, but since Cache Store uses two phase commit, and multiple Cache Stores will need to use "three phase commit", and there's no such thing - that you can expect data inconsistency on edge cases.
Happy path should, however, work OK.
The Situation
I'm building a C# web application and I want to model my app configuration as an explicit dependency to be handed in through the constructor of a service instead of relying on System.Configuration.ConfigurationManager directly in each of the classes. This did bite my quite often in the past so I want the dependency to be explicit so that the next maintainer of the project (probably future me) doesn't have to guess where my services get their configuration settings - on top of that it is more TDD friendly. Furthermore I'm currently reading Eric Evan's Domain Driven Design and I really want to embrace his DDD approach.
I started modeling the configuration class and corresponding value objects to avoid Primitive Obsession but I hit some bumps on the way and I'm not sure how to handle them appropriately. Here is my current approach:
// Role interface that can be requested via constructor injection
interface IAppConnectionStringsConfig
{
OleDbConnectionString AuthenticationConnectionString { get; }
}
// A base class for handling common functionality like
// parsing comma separated lists or default values
class abstract AppConfigBase
{
protected string GetStringAppSetting(string key)
{
// Get the appropriate string or a default value from
// System.Configuration.ConfigurationManager
return theSettingFromSomeConfigSource;
}
}
// A value object for OLEDB connection strings that also has a
// convenient implicit conversion to string
class OleDbConnectionString
{
public readonly string Value;
public OleDbConnectionString(string connectionString)
{
Contract.Requires(connectionString != null);
this.VerifyStructure(connectionString);
this.Value = connectionString;
}
private void VerifyStructure(string text)
{
Contract.Requires(text != null);
// Verify that the given string fulfills the special
// needs of an OleDbConnectionString (including Provider=...)
if (!/* isValidOleDbConnectionString */)
{
throw new FormatException();
}
}
public implicit operator string(ConnectionString conn)
{
return conn.Value;
}
}
// The actual app config that implements our role interface
class AppConfig : AppConfigBase, IAppConnectionStringsConfig
{
public OleDbConnectionString AuthenticationConnectionString
{
get
{
return new OleDbConnectionString(this.GetStringAppSetting("authconn"));
}
}
}
The Problem
I know that constructor logic should be minimal and that is not a good idea to call virtual methods from the constructor. My questions are as follows:
1) Where should I put the validation logic for the OleDbConnectionString? I really want to prevent the creation of value objects in an invalid state - that's excrutiatingly usefull at a day to day basis :-)
I have the feeling that this is domain logic that should be owned by the class itself but on the other hand the constructor should do as little as possible - wouldn't the string parsing be too much or is this ok?
I could create a validator but I most certainly had to hand that in through the constructor for being able to test that thing properly and then I have to wire that manually or use a factory (I'm definitely not using a Service Locator). On top of that the validation now would be hidden in a separate service; I wouldn't have the temporal coupling since the constructor requires the validator but still that doesn't look right.
2) I wonder if it would be appropriate to make DDD value objects structs? They - like the name suggests - represent a single value and this value is immutable. But they would contain business logic in the form of validation
3) Is it OK to use a property for retrieving the connection string? It could throw an exception if the format for the string isn't valid. Furthermore it's perfectly possible that the implementation will be changed from reading from an xml config file to querying a database.
4) Any other comments on the design are welcome!
As a side note, I'm already using Code Contracts and there is a way to specify object invariants but I don't know whether this is really a good idea since these contracts are opt-in and in the case that they are inactive the invariants are no longer actively protected. I'm not sure about this, for development purposes to catch errors early it might be fine but for production it seems off.
Thx!
I never really thought about general settings as a DDD problem - are you modelling a domain that is about settings and how they are saved, or just allowing settings to be saved and used in an application that has some inner parts modeled as DDD?
You can split this out by separating concerns of getting settings away from the things that use the settings.
Is it OK to use a property for retrieving the connection string? It could throw an exception if the format for the string isn't valid.
I don't think its a good idea to throw an exception if a setting cannot be retrieved so you can return defaults which would allow the program to continue.
But also remember that the default returned value (i.e. a password, or network address) will probably cause the thing that depends on that setting to throw an exception.
I would look at allowing the construction to happen OK but when coming to use the service i.e. Sender.Send() or Sender.Connect() is when you would throw an exception.
Where should I put the validation logic for the OleDbConnectionString? I really want to prevent the creation of value objects in an invalid state
I create objects that can never return an invalid result, but they do return a default settings value:
public class ApplicationSettings : IIdentityAppSettings, IEventStoreSettings
{
/* snip */
static readonly object KeyLock = new object();
public byte[] StsSigningKey
{
get
{
byte[] key = null;
lock (KeyLock)
{
var configManager = WebConfigurationManager.OpenWebConfiguration("/");
var configElement = configManager.AppSettings.Settings["StsSigningKey"];
if (configElement == null)
{
key = CryptoRandom.CreateRandomKey(32);
configManager.AppSettings.Settings.Add("StsSigningKey", Convert.ToBase64String(key));
configManager.Save(ConfigurationSaveMode.Modified); // save to config file
}
else
{
key = Convert.FromBase64String(configElement.Value);
}
}
return key;
}
/* snip */
}
}
What I generally do
I have the settings interfaces for each bounded context defined in the domain model as part of the infrastructure - this allows a number of known interfaces which I can reference and trust to provide some form of settings.
ApplicationSettings is defined in the code that hosts my bounded context(s) be it a Console app or WebAPI or MVC etc, I may have multiple bounded contexts hosted under the same process, or may split them out as separate processes, either way it is the job of the hosting application to provide the relevant application settings and wiring can be done via the IoC container.
public class ApplicationSettings : IIdentityAppSettings, IEventStoreSettings
{
// implement interfaces here
}
public interface IEventStoreSettings
{
string EventStoreUsername { get; }
string EventStorePassword { get; }
string EventStoreAddress { get; }
int EventStorePort { get; }
}
public interface IIdentityAppSettings
{
byte[] StsSigningKey { get; }
}
I use SimpleInjector .NET IoC container to wire up my applications. I then register all the application interfaces with SimpleInjector (so i can query based on any of the application interfaces and have the settings class object returned):
resolver.RegisterAsImplementedInterfaces<ApplicationSettings>();
I can then have the specific interface injected in, an example is a command handler that uses an IRepository, which in turn the EventStoreRepository (which is wired up as an implementation of IRepository) uses IEventStoreSettings (which is wired up as the ApplicationSettings instance):
public class HandleUserStats : ICommandHandler<UserStats>
{
protected IRepository repository;
public HandleUserStats(IRepository repository)
{
this.repository = repository;
}
public void Handle(UserStats stats)
{
// do something
}
}
And my repository would in turn be wired up:
public class EventStoreRepository : IRepository
{
IEventStoreSettings eventStoreSettings;
public EventStoreRepository(IEventStoreSettings eventStoreSettings)
{
this.eventStoreSettings = eventStoreSettings;
}
public void Write(object obj)
{
// just some mockup code to show how to access setting
var eventStoreClient = new EventStoreClient(
this.eventStoreSettings.EventStoreUsername,
this.eventStoreSettings.EventStorePassword,
this.eventStoreSettings.EventStoreAddress,
this.eventStoreSettings.Port
);
// if ever there was an exception either during setup of the connection, or
// exception (if you don't return a default value) accessing settings, it
// could be caught and bubbled up as an InfrastructureException
// now do something with the event store! ....
}
}
I allow settings to be passed in from some external source (like a WCF receive, or MVC controller action) and wired up by getting resolver.GetInstance<CommandHandler<UserStats>>(); which wires up all the settings for me all the way down to the implementation level.
I have a MVC application with all Ninject stuff wired up properly. Within the application I wanted to add functionality to call a WCF service, which then sends bulk messages (i.e. bulk printing) to RabbitMQ queue .
A 'processor' app subscribes to messages in the queue and process them. This is where I also want to update some stuff in the database, so I want all my services and repositories from the MVC app to be available too.
The processor app implements the following:
public abstract class KernelImplementation
{
private IKernel _kernel;
public IKernel Kernel
{
get
{
if (_kernel != null)
return _kernel;
else
{
_kernel = new StandardKernel(new RepositoryModule(),
new DomainModule(),
new ServiceModule(),
new MessageModule());
return _kernel;
}
}
}
}
All Ninject repository bindings are specified within RepositoryModule, which is also used within MVC app and look like this:
Bind<IReviewRepository>().To<ReviewRepository>().InCallScope();
The processor class
public class Processor : KernelImplementation
{
private readonly IReviewPrintMessage _reviewPrintMessage;
public Processor()
{
_reviewPrintMessage = Kernel.Get<IReviewPrintMessage>();
[...]
_bus.Subscribe<ReviewPrintContract>("ReviewPrint_Id",
(reviewPrintContract) => _reviewPrintMessage.ProcessReviewPrint(reviewPrintContract));
//calling ProcessReviewPrint where I want my repositories to be available
}
}
Everything works fine until I update the database from the MVC app or database directly. The processor app doesn't know anything about those changes and the next time it tries to process something, it works on a 'cached' DbContext. I'm sure it's something to do with not disposing the DbContext properly, but I'm not sure what scope should be used for a console app (tried all sort of different scopes to no avail).
The only solution I can think of at the moment is to call WCF service back from the processor app and perform all the necessary updates within the service, but I would want to avoid that.
UPDATE: Adding update logic
Simplified ReviewPrintMessage:
public class ReviewPrintMessage : IReviewPrintMessage
{
private readonly IReviewService _reviewService;
public ReviewPrintMessage(IReviewService reviewService)
{
_reviewService = reviewService;
}
public void ProcessReviewPrint(ReviewPrintContract reviewPrintContract)
{
var review =
_reviewService.GetReview(reviewPrintContract.ReviewId);
[...]
//do all sorts of stuff here
[...]
_reviewService.UpdateReview(review);
}
}
UpdateReview method in ReviewService:
public void UpdateTenancyAgreementReview(TenancyAgreementReview review)
{
_tenancyAgreementReviewRepository.Update(review);
_unitOfWork.Commit();
}
RepositoryBase:
public abstract class EntityRepositoryBase<T> where T : class
{
protected MyContext _dataContext;
protected EntityRepositoryBase(IDbFactory dbFactory)
{
this.DbFactory = dbFactory;
_dbSet = this.DataContext.Set<T>();
}
[...]
public virtual void Update(T entity)
{
try
{
DataContext.Entry(entity).State = EntityState.Modified;
}
catch (Exception exception)
{
throw new EntityException(string.Format("Failed to update entity '{0}'", typeof(T).Name), exception);
}
}
}
Context itself is bound like this:
Bind<MyContext>().ToSelf().InCallScope();
From the description of scopes I thought that Transient scope was the right choice, but as I said earlier I tried all sorts including RequestScope, TransientScope, NamedScope and even Singleton (although I knew it wouldn't be desired behaviour), but none of them seem to be disposing the context properly.
What you'll need is one DbContext instance per transaction.
Now other "applications" like web-applications or wcf-service may be doing one transaction per request (and thus use something like InRequestScope(). Also note, that these application create an object graph for each request. However, that is a concept unknown to your console application.
Furthermore, scoping only affects the instantiation of objects. Once they are instantiated, Scoping does not have any effect on them.
So one way to solve your issue would be to create the (relevant) object tree/graph per transaction and then you could use InCallScope() (InCallScope really means "once per instantiation of an object graph", see here).
That would mean that you'd need a factory for IReviewPrintMessage (have a look at ninject.extensions.factory) and create an instance of IReviewPrintMessage every time you want to execute IReviewPrintMessage.ProcessReviewPrint.
Now you have re-created the "per request pattern".
However, regarding CompositionRoot this is not recommended.
Alternative: you can also only re-create the DbContext as needed. Instead of passing it around everywhere (DbContext as additional parameter on almost every method) you use a SynchronizationContext local storage (or if you don't use TPL/async await: a ThreadLocal). I've already described this method in more detail here
I'm doing an application for a Windows CE 5.0 device that asks for the username in the first form (when the application is launched), and then I get the userId from a database table.
After that a menu form appears which receives the userId, and I have to send to each constructor of the menu options the userId in order to use it in those forms. I assume there must be a better way to do something like this.
Example:
public partial class Menu : Form
{
int userId;
public Menu(int userId)
{
InitializeComponent();
this.userId = userId;
}
private void buttonDelivery_Click(object sender, EventArgs e)
{
Delivery delivery = new Delivery(userId);
delivery.Show();
this.Hide();
}
...
May be I should use a global variable like this?
public static class UserConfiguration
{
public static int userId;
}
Isn't that also bad practice?
Finally bear in mind that compact framework doesn't support app.config files
Personally I'd vote for "neither", but would instead use some other architectural tools available.
I'd be highly inclined to have a class that incorporates all user info (the ID you're using and then maybe anything else, like name, etc). I'd create an instance and populate that info when the first Form (login) is submitted and I'd keep it in a DI container (I use this one specifically, but any CF-supporting container would work).
I'd then either use injection to either automatically push that instance into any class that needs it, or have the consumer pull it from the container as needed. Which mechanism I use would depend on which container I'm using and exactly how/when I need the info.
Since the data you're after is coming from a database, I'd actually be inclined to use an ORM (I use this one) to pull the data, which would give you the entity instance containing the user info you're after automatically anyway.
in my opinion both ways are good, in some cases some controls do not work properly if you change the constructor signature or in some cases your constructor would not be called if the framework always calls the one with no parameters. But really depends on the specific case.
I like more the method parameters way to pass the values, but the external class with static field would also work fine.
P.S. app.config is not the best place anyway to store runtime specific values so doesn't matter if supported or not by CF in this case ;-)
If you use a controller it can hold all the variables needed. The controller can have a static Instance property that instantiates itself (see Singleton object design pattern). When developing Mobile applications this is very common as memory is often a constraint. The rest of the methods are public members (not static) so you would access like this. You can either make them properties or just use the public member. Even with mobile we tend to not use properties as it just adds unecessary fluff and boxing/unboxing.
In one form you can use:
MainController.Instance.loginID = "me123";
on another you can use
MessageBox.Show("my loginID is: " + MainController.Instance.loginID);
You can also add methods like:
MainController.Instance.ClearSession();
Which internally just sets loginID to null. etc. Personally I use the main controller to show windows as well. Because in mobile we need to make sure our resources are cleaned up as well.
MainController.Instance.ShowLoginForm();
the MainController code as a start should look something like this:
public class MainController : IDisposable {
//all forms we are controlling
LoginForm _loginForm = null;
//all public members
public string loginID = null;
#region Singleton Instance stuff
private static MainController me = null;
private void MainController() { }
public static Instance {
get {
if(me == null) {
me = new MainController();
}
return me;
}
}
#endregion
//all public methods
public void Init(someargshere) {
//TODO some init like load config files, etc.
}
public void Dispose() {
//TODO cleanup
}
public void ClearSession() {
loginID = "";
}
public void ShowLoginForm() {
if(loginForm!=null) {
loginForm.Dispose();
loginForm == null;
}
loginForm = new LoginForm();
loginForm.Show();
loginForm.BringToFront();
}
//etc
}
So the very first thing you do in the Program.cs code is init your main controller
main(string[] args) {
//start a controller
MainController.Instance.Init(passomeargs if needed);
//now fire off our main form
Application.Run(new MainForm());
}
Now all forms there after can access it's data through the MainController
Personally I use commands and have the main controller hide and show forms based on the commands passed in so there is as little logic in the forms as possible. This may or may not lend well to what you are doing.
Good luck