I'm attempting to architect a solution involving a WCF service, which calls a dll containing an EntityFramework6 model. When I attempt to unit test the service however, I receive a message:
Additional information: No connection string named 'SyslogEntities' could be found in the application config file.
My flow is arranged logically as:
SyslogDataSvcTest.dll (app.config has service bindings) ->
SyslogDataSvc.svc (web.config has provider and connection string) ->
LibSyslogData.dll (app.config has providers and connection string)
All the code that touches EF is in the libSyslogData.dll. It maps data to upper layer objects internally, and returns them, instead of exposing its own model info, so EF use should be really isolated.
So what am I doing wrong?
Edit:
I got it working well, but in perhaps a weird way. It seems the settings in my app.config were not correctly specified by NuGet when installing the EF and MySql dependencies.
Instead I created an in-code configuration class as described on MSDN here:
https://msdn.microsoft.com/en-us/data/jj680699
Now that I have this class:
public class EFConfiguration : DbConfiguration {
public EFConfiguration()
{
//For some reason this works much better than the app.config.
//With this defined, upper layer config documents need only specify the "SyslogEntities" Connection string.
SetExecutionStrategy("MySql.Data.MySqlClient", () => new MySqlExecutionStrategy());
SetDefaultConnectionFactory(new MySqlConnectionFactory());
SetProviderFactory("MySql.Data.MySqlClient", new MySqlClientFactory());
SetProviderServices("MySql.Data.MySqlClient", new MySqlProviderServices());
}
}
I can leave the specifics of the DB implementation to the datalayer, and only configure the connection string at the upper layers.
You most likely don't test the actual wcf service (I mean online) based on that exception. I think you are just unit testing the wcf service dlls code. So this would mean the app.config used is from the unit test assembly. Just 1 app.config for runtime for application, having an app.config for a class library does not make sense anyway either.
You need to provide the EF connectionstring that your EF data-access layer is using in your unit test assemblies, as you are doing in your wcf services web.config (since you are not testing the online wcf service). If you want to be totally free of EF references in your unit tests and wcf service configs, you need to override the default constructors for your EF entities and provide the "normal" dbprovider + connectionstring in your app/web configs and create the EF connection string(s) on the fly.
Related
I am working on n-tier application, where I have Data Access Layer. which is independent to any other application. I have create Class Library for .NET Core 1.1, I can see dependencies folder but not any config/JSON file. I want to know, Can I add AppSetting.JSON file in class library project? followed by how can I add connection string. I am aware to override ConfigureBuilder in DbContext class --> SQLServerConnection but I want to keep in separate config file and refer to these connection strings.
Also to note, This class library will not link to ASP.NET application directly
While searching on google, I have found following link https://www.stevejgordon.co.uk/project-json-replaced-by-csproj but my question remains, where and how I add connection string for Class Library project?
You've kind of got this the wrong way round. You dont want to have a config file for your DAL assembly, you simply want your DAL to know nothing at all about configuration!
Typically, all you configure for a DAL is a conection string and this can easily be passed in on a constructor:
public class MyRepository : IMyRepository
{
public MyRepository(string connectionString){ ... }
}
When you use this DAL in something like a webapi chances are you'll be using Dependency Injection - and it's here you would read the conn string from the web api's configuration
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Configuration.GetConnectionString("MyConnectionString");
services.AddScoped<IMyRepository>(sp => new MyRepository(connectionString));
}
I currently have one Web Service in a solution of multiple projects. Since I don't want to add service references in all project to be able to use it, I have created a project with static a class named "ServiceHelper" for the moment. This project would be the only one with the service references and the helper would do all the request ncessary. The Web Service is set public (not internal).
My problem here is that when I initialize my SoapClient in my helper from another project that do not have the service references, it throws an exception. But when I add the service reference to that other project, it works. Is it normal or not?
The exception throwed translated (because it is said in French) is :
Unable to find an element endpoint default refers to the contract 'ServiceReference.WebServiceSoap' section in the ServiceModel client configuration. This may be due to the fact that the configuration file of your application is not found or the endpoint element matching this contract is found in the client element
Is there something missing in my config file? because I didn't change anything in the 2 projects mentionned.
Exemple of how I initialize my SoapClient in my helper :
private static ServiceReference.WebServiceSoapClient _webService = new ServiceReference.WebServiceSoapClient();
Following on with #zverev.eugene, you don't need the references in every project, but the web.config or app.config in the project is where the connection and configuration information is retrieved from. This is because the application calling your class library is what supplies all configuration information (e.g., if you have a data access layer in a class library, the connection string would come from the .config of the application calling the DAL, not the class library itself).
I have 2 C# .net applications such as
1. A data access applicatin which has an entity frame work data model to connect to the DB.
2. A web application which will contain the dll of 1st application and getting data by calling functions from dll
I need to take the connection string from the 2nd application web config file and pass it to the 1st application. In the 1st application data should be retrieved according to the connection string from the 2nd application.
There are quite a few ways you can achieve this. One (which I won't go into here) is through some kind of bootstrap loader - where you pass a connection string via the constructor of your repository (or data context), or you could construct a SqlConnectionStringBuilder (some further details here).
If you want to keep things simple, store the connection string in your web.config file of your web application, set the key to the name of your object. So let's say you have extended DbContext with an object called MyDbContext. In the web.config you'll have the following as your connection string
<add name="MyDbContext" connectionString="<conn string>" providerName="System.Data.SqlClient" />
Entity framework will use this connection string automatically, as the key is the same as your context.
If the dll is to act as a data access layer, it should be retrieving the data and passing it to the web application. Not the other way around.
If you choose to do it that way anyway, you'll have to make a function that retrieves the connection string from the app.config of the dll and pass it to the web app.
To access the connection string(s) in the config file of an assembly, us the ConfigurationManager class, (opposed to the WebConfigurationManager class that you would use in a web application). It accesses the elements of the config in the same maner with teh same calls, just intended for generalized config reads/writes.
EDIT: As mentioned by #PaulAldred-Bann, the connection string "should" be stored in the web apps config file if it is needed in the web app as well. The assembly would still have access to this (you would just move the settings to the web.config from the app.config. The reason it can be accessed from there is, the assembly, when referenced, acts on behalf of the caller (in this case, the web app).
I would like to use WCF RIA Services to access data from my Silverlight Application. However the data is not provided from a local data storage, but from another WCF Data Service (I'm accessing an external CRM system). I don't want to access the external service directly because I have to mash up data from several data sources within my RIA service.
Is this possible an what would be the easiest way to achieve this? Some source code in C# would be appreciated.
EDIT:
The central problem is how to fill an entity from an external service in an easy way. There is a related question, but the answer does not solve my problem.
I think your confusion may be that the Visual Studio wizard for adding a RIA service assumes you will use the EntityFramework for your data. I don't think you want to create an EF model out of the data from a second WCF service. Instead, create your RIA service to derive directly from DomainService and override the methods that you need. In each query method, simply query the remote service and return the result to the Silverlight client. In order for the RIA services magic code generation to work you will need to define a set of DTO objects in your app that wrap the results from the remote WCF service.
Here is a quick sample. Note - I just made this up to illustrate what I mean. You will need to put in calls to the actual service you are using and build error handling, input checking, etc.
namespace YourApp.Web
{
[EnableClientAccess]
public class WcfRelayDomainService : DomainService
{
public IQueryable<Restaurant> GetRestaurants()
{
// You should create a method that wraps your WCF call
// and returns the result as IQueryable;
IQueryable<MyDto> mydtos = RemoteWCF.QueryMethod().ToQueryable();
return mydtos;
}
public void UpdateDTO(MyDto dto)
{
// For update or delete, wrap the calls to the remote
// service in your RIA services like this.
RemoteWCF.UpdateMethod(dto);
}
}
}
Hope that helps you out! See How to set up RIA services with Silverlight 4.0 and without EF for some more tips.
A little background:
I'm creating a set of adapters to allow communication with mobile devices over different cellular networks. This will be achieved using a class factory pattern. At least one of the networks requires a service reference to communicate with their devices through a web service.
So far I've got 3 assemblies so far which represent:
An assembly which contains the main adapter library: this contains
The interface definition for each of the adapters
Base classes
The class factory to instantiate the specified adapter at runtime.
An assembly for each network adapter implementation.
An assembly that contains my main application.
Given that I don't want to be adding service references and their configuration to the main application assembly [as that's not relevant to the main application], how do I force each assembly's service reference to get its configuration from its own app.config?
If I have the service reference configuration in the main app.config, everything works just fine, but if I move the configuration to the adapter's app.config everything stops working throwing the following exception at the point where I new up the Soap1Client.
"Could not find default endpoint element that references contract 'MobileService.Service1Soap' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element."
In the end, I just removed the service reference and added a web reference [i.e. did it the 2.0 way]. For some reason the web reference will access its own app.config instead of the main application's app.config.
Far easier than the alternative...
You can set all the options programatically.
I don't believe there is a built in .NET way to accomplish this. However you should be able to accomplish it by writing some code to parse each referenced assembly's .config file.
Here is a sample using assembly specific configuration files that should point you in the right direction: http://www.bearcanyon.com/dotnet/#AssemblySettings.
I've done something similar in a .NET Winforms app and it worked out well.
If you must have the library read the configuration for the service from a config file, then you might be out of luck. The library becomes part of the process and the process uses the configuration of the application that initiated the process.
However, in your library you could use one of the service reference proxy class constructor overloads to dynamically set the configuration when you instantiate the service reference. Then you don't have to have the service reference binding configuration in any config file. The overload I use takes two parameters: System.ServiceModel.Channels.Binding binding & System.ServiceModel.EndpointAddress remoteAddress. Note that the Binding class is a abstract class, you have to use one of the classes that inherit from it - you can find a list of them here: https://msdn.microsoft.com/en-us/library/system.servicemodel.channels.binding(v=vs.110).aspx.
For a simple http service reference I use a default instance of the BasicHttpBinding class and create an instance of the EndpointAddress class using the URL of the service I'm referencing. Obviously you would have to modify this to use https or secured services, etc.
Of course this still begs the question of how does the library get the correct service URL if you don't want to hard code it in the library? A couple of ways would be to read it from a database or a known file location.