Setting Bugsnag configuration options in code - asp.net

In the documentation it says that I can do the following in code to further configure my integration:
Each key provides an in code example and a config file example.
configuration.ReleaseStage = "development";
What I am trying to do is:
public static void Register(HttpConfiguration config)
{
var configuration = Bugsnag.ConfigurationSection.Configuration.Settings;
configuration.ReleaseStage = ConfigurationManager.AppSettings["Environment"];
config.UseBugsnag(configuration);
}
However, the configuration properties are read-only (don't have setters).
The alternative is to add the configurations to the Web.config:
<bugsnag apiKey="your-api-key" releaseStage="development">
The problem is that I am reading my environment from the AppSettings and therefore cannot do it this way.
Is it possible to do the configuration in code and if so, how?
UPDATE: Since posting the question I have found the issue on GitHub.

From the GitHub issue it seems as if this isn't possible so I used the work around suggested by one of the project's contributors.
The only work around I can suggest right now is to use the core Bugsnag nuget package...
I removed all the 'old' code, uninstalled all the NuGet packages except for the base Bugsnag and added the following code to the OnException override method where I had been logging exceptions up until now.
var configuration = new Configuration("API_KEY")
{
ReleaseStage = myReleaseStage
};
var client = new Bugsnag.Client(configuration);
client.Notify(new System.Exception("Error!"));
This worked and errors are now logged along with the environment in which they occurred. My next step will be to refactor this work around so that client is available globally but for now this solves my in code problem.

From Bugsnag's latest Go documentation, you can programmatically set the release stage. In your example, it would look like this:
configuration.ReleaseStage = ConfigurationManager.AppSettings["Environment"];

Related

How to get appsettings from project root to IDesignTimeDbContextFactory implementation in ASP.NET Core 2.0 and EF Core 2.0

I am building an application in ASP.NET Core 2.0 and I am having problems with EntityFramework Migrations.
I have my DbContext in a separate project (SolutionName\ProjectNamePrefix.Data) and therefore I created an implementation for the IDesignTimeDbContextFactory interface.
I wanted to use different connection strings for different environments and I need appsettings.json for that.
So after a quick search I found that I can create a new IConfigurationRoot object inside the CreateDbContext function as shown here:
https://codingblast.com/entityframework-core-idesigntimedbcontextfactory/
I added that and then for testing, tried to run dotnet ef migrations list -c MyContext from the Data project root folder.
Then I got the following error:
The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\dev\*SolutionName*\*ProjectNamePrefix*.Data\bin\Debug\netcoreapp2.0\appsettings.json'.
So, basically, I tried 3 options for getting the correct root path:
Directory.GetCurrentDirectory();
env.ContentRootPath; (IHostingEnvironment object, I found a way to get it here: https://github.com/aspnet/Home/issues/2194)
AppDomain.CurrentDomain.BaseDirectory;
and all of them returned the same ..\bin\debug\netcoreapp2.0\ path. When I run the Data project from VS, then the two first options give me the correct project root folder.
Is there a way to get the correct project content root folder?
Because when I added --verbose to the EF command, it logged out a row:
Using content root 'C:\dev\FitsMeIdentity\FitsMeIdentity.Data\'.
So I understand that EF somehow knows the project root but all the options mentioned above return the path for the already built application.
The only option I found that works is that I change Copy output to root folder to Copy always but found from here: https://www.benday.com/2017/02/17/ef-core-migrations-without-hard-coding-a-connection-string-using-idbcontextfactory/ that it's not a good idea.
At first I even thought about creating a Constructor for the IDesignTimeDbContextFactory implementation which gets IOptions as a parameter but that didn't work, had the same problem as explained here:
Injecting Env Conn String into .NET Core 2.0 w/EF Core DbContext in different class lib than Startup prj & implementing IDesignTimeDbContextFactory
A little late, but here is the solution for those who hate hard-coding connections strings:
internal class MigrationDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{
public AppDbContext CreateDbContext(string[] args)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", false)
.Build();
string connectionString = configuration.GetConnectionString("DefaultConnection");
DbContextOptionsBuilder<AppDbContext> optionsBuilder = new DbContextOptionsBuilder<AppDbContext>();
optionsBuilder.UseMySql(connectionString,
ServerVersion.AutoDetect(connectionString),
mySqlOptions =>
mySqlOptions.EnableRetryOnFailure(
maxRetryCount: 10,
maxRetryDelay: TimeSpan.FromSeconds(30),
errorNumbersToAdd: null));
return new AppDbContext(optionsBuilder.Options);
}
}
No. You can't do this, and more to the point: you're not supposed to do this. The whole entire point of IDesignTimeDbContextFactory is that it's a way to get a DbContext instance from in a context where there is no ASP.NET Core framework to work with, i.e. from a class library. If you're running migrations from an ASP.NET Core project, you don't need it, and if you're not, none of the configuration stuff is available.
Additionally, it's only to be used for development, hence the "DesignTime" part of the name. As a result, there's no need for stuff like switching between connection strings for different environments. Just hard-code the connection string as the docs detail.

Enterprise Library not logging in setup project

I need your opinion on this: Is it possible to use enterprise library logging dll in the setup project?
Here's what I did:
I created a setup project which will call a windows form to install the database. When I installed the project, it did call the windows form. However, when I click on the "Install" button, it seems that there's a problem and I don't know where it is. Then another popup message is displayed which said that it cannot locate the logging configuration.
But the config file for the windows form is there which includes the configuration for the logging dll. I don't have any idea where to look into.
Please help me with this?
Below is the error message:
UPDATE
I observed that when I run the exe file as is, the enterprise library logging config works. But with the setup project, it does not look for it. Any help on this?
Below is the code for this:
[RunInstaller(true)]
public partial class IPWInstaller : Installer
{
public IPWInstaller()
{
InitializeComponent();
}
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
string targetPath = Context.Parameters["TargetDir"];
InstallDatabase db = new InstallDatabase(targetPath);
DialogResult dbResult = db.ShowDialog();
if (dbResult != DialogResult.OK)
{
throw new InstallException("Database is not installed.");
}
ConfigureFiles config = new ConfigureFiles(targetPath);
DialogResult configResult = config.ShowDialog();
if (configResult != DialogResult.OK)
{
throw new InstallException("Config files are not saved correctly.");
}
}
}
LATEST UPDATE:
I tried to set the value of a certain configuration to my messagebox. This is the result of it when I run the install project.
Is there a way to call my app.config in the setup project
There are at least a couple of things that can go wrong.
The app is not running as it would if you ran it as an interactive user. It is being called from an msiexec.exe process that knows nothing about your intended environment, such as working directory. None of the automatic things that happen because you run from an explorer shell will happen. Any paths you use need to be full and explicit. I think you may need to explicitly load your settings file.
Something else that can happen in a per machine install is that custom actions run with the system account so any code which assumes you have access to databases, user profile items like folders can fail.
Another problem is that Windows Forms often don't work well when called from a VS custom action. It's not something that works very well because that environment is not the STA threading model that is required for window messages etc.
In general it's better to run these config programs after the install the first time the app starts because then you are in a normal environment, debugging and testing is straightforward, and if the db gets lost the user could run the program again to recreate it instead of uninstalling and reinstalling the setup.

Caliburn.Micro IEventAggregator Publish method missing an overload

I'm working through some tutorials online learning Caliburn.Micro for the first time. Some of the tutorials are using the older 1.3.0 version, I'm using the newer 2.0.0.6 version which was the latest Nuget package which is likely the source of this discrepancy:
When trying to publish the following message:
public void Red()
{
_events.Publish(new ColorEvent(new SolidColorBrush(Colors.Red)));
}
The compiler throws an error saying that the overload wasn't found. The only overload for Publish that is available has the following signature:
void Publish(object message, Action marshal)
I got this to work by using the background worker thread method shown below but in my case it seems like overkill. Was the single parameter overload really removed from Caliburn.Micro?
Also, the documentation is here:
https://caliburnmicro.codeplex.com/wikipage?title=The%20Event%20Aggregator
still show examples using the more basic, single parameter example where you simply pass a message. Is the documentation at this link the latest that correctly describes 2.0.0.6?
public void Red()
{
_events.Publish(new ColorEvent(new SolidColorBrush(Colors.Red)),
action => Task.Factory.StartNew(action));
}
Finally, for bonus points:
What is this 2nd parameter good for other than publishing the message on a background thread? Can someone give some other example(s) of what this overload can be used for?
In Caliburn Micro version 2.0, the EventAggregator.Publish method also takes an action to marshal the event. To maintain the pre-2.0 behavior, you should switch to the EventAggregator.PublishOnUIThread method instead. See the migration instructions here for information on incompatibilities between 1.5 and 2.0.
In general, I believe that the Codeplex documentation is a little bit outdated. Please refer to the new dedicated web site for most up-to-date documentation.

can't register objects using unity 2.0

I created a web service recently and am using unity to inject my object dependencies. My composition root is the Application_Start in the web services and am using the web.config to do my object to interface mappings. Everything was working fine, however after i loaded my project into tfs i keep getting an error stating that it cant resolve one of the interfaces. I removed the code to register my objects from the web.config and regsistered them in code instead to test and it all works fine. Any ideas what the problem is. Any ideas how i can troubleshoot this problem.
Before TFs :-
UnityContainer uContainer = new UnityContainer();
UnityConfigurationSection Section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
Section.Configure(uContainer, "CentralRepositoryContainer");
Application["uContainer"] = uContainer;
Amended code which works fine :-
UnityContainer uContainer = new UnityContainer();
uContainer.RegisterType<ICentralRepositoryLifeTimehelper, CentralRepositoryLifeTimeHelper>();
uContainer.RegisterType<IJobsHandler, JobsHandler>();
Application["uContainer"] = uContainer;
I don't know the problem, but to troubleshoot print out all the Unity containers registrations and see what's missing/changed.
Use the code sample from Retrieving Container Registration Information

Class will compile for Tests/Console but not in Asp.net application

I have a simple interface:
public interface IVisitorsLogController
{
List<VisitorsLog> GetVisitorsLog();
int GetUniqueSubscribersCount();
int GetVisitorsCount();
string GetVisitorsSummary();
}
the class VisitorsLogController implements this interface.
From a console application or a TestFixture - no problem - the console/test fixture compile perfectly.
However, from an Asp.Net web site (not application) in the same solution with this code in the code behind
private IVisitorsLogController ctl;
protected int GetUniqueMembersCount()
{
ctl = new VisitorsLogController();
return ctl.GetUniqueSubscribersCount();
}
the compiler throws this exception:
Error 1 'WebSiteBusinessRules.Interfaces.IVisitorsLogController'
does not contain a definition for
'GetUniqueSubscribersCount' and no
extension method
'GetUniqueSubscribersCount' accepting
a first argument of type
'WebSiteBusinessRules.Interfaces.IVisitorsLogController'
could be found (are you missing a
using directive or an assembly
reference?)
yet for this code in the same file:
protected static int GetVisitorsCount()
{
return VisitorsLogController.Instance.GetVisitorsCount(DateTime.Today);
}
the compiler compiles these lines without complaining. In fact if I add anything new to the Interface the compiler now complains when trying to compile the asp.net page.
It can't be a missing using directive or assembly reference otherwise both methods would fail.
This is driving me nuts!
Any thoughts please?
Thanks,
Jeremy
Out of interest, can you compile the following line:
ctl = VisitorsLogController.Instance;
? I'm just wondering if somehow you've got two interfaces named the same thing.
What does Intellisense prompt you with when you type ctl. and press Ctrl-Space?
It would seem the other important bit of code would be VisitorsLogController, wouldn't it? It looks like VisitorsLogController is implementing a different IVistorsLogController interface.
Right clicking and GoTo Definition should clear things up, I think.
I would start by checking the namespaces on each of the files involved and make sure that you don't have a conflict or a namespace that you are not expecting.
The solution contains the web site and three class projects (Data Layer, Service Layer and Core Services). They are added as references to the web site as Projects.
I had compiled the solution at one point for Release - published the site, and then changed the config to Debug.
Evidently what had happened was that the Release dll's in the /bin file of the website were not being overwritten by the new Debug dll's. I manually deleted all the files in the /bin directory, and lo and behold - everything compiled perfectly.
So Mark and John - you were both spot on - I effectively did have two interfaces named the same thing.
Thanks very much for your help - if you hadn't given me these pointers I would never have finally worked it out.

Resources