Initialize ASP.NET Core Web API from another project - c#

I have an application that is structured as follows:
Class A with certain methods exposed
Class B that basically acts as the command line interface, calling the exposed methods of an instance of class A
Class B's constructor takes an instance of class A as an argument and works with that instance from then on.
public class B
{
private A ainstance
public B(A ainstance)
{
this.ainstance = ainstance;
}
}
class Program
{
void Main()
{
var x = new A();
var y = new B(x);
}
}
This structure has worked fine so far. Now however I need to implement an API so that the same operations can be performed on A from a web interface. I chose to use .NET Core for the API, and have implemented most of it. My plan was to add a reference for the API project to the original project and then call the startup method from my Main(), once gain passing the instance of class A as an argument. This doesn't work. Visual Studio refuses to add the reference for reasons unknown.
Is there a way to implement my original idea? If not then ideas for an alternative structure would be greatly appreciated.

As it turns out, all I needed to do to get it to work was to use create .NET Core Console Application project instead of a normal Windows one.
When I was trying with a normal Console Application project, Visual Studio gave a misleading error: "A reference to [API project name] could not be added. An assembly must have a 'dll' or 'exe' extension in order to be referenced", which led to my confusion. I discovered the actual problem when I tried doing the reverse (referencing the console project from the API one), and VS showed the framework incompatibility.

What I understood that your Class A and Class B will remain same except the Class 'Program' logic in your example will go in Asp.NET page.
I think you just needed to create a Library project and put the old logic withing this ie: Class A and Class B, compile it, reference this library output in your Asp.Net application, you should be good to go.

Related

How to change from WSDL reference when switching environments from dev to production, for example

My team is building an API which interfaces with another API with many endpoints. Our app is in .net core, so we've been using the connected services wizard for each reference. This means we had to specify the URI's for our endpoints.
Everything is working as expected, but when we move out of dev/qa to staging, all of those references will be wrong, and I will have to manually switch the connected service url's (I think I can do this by simply accessing the ConnectedService.json for each reference and changing extended data: inputs: "[url]" to the different url, but that would mean changing ~20 (so far) references every time we change environments.
My boss says it will become unmanageable as the scope widens. Is there a way to implement dependency injection for service reference uri's so that when the env changes, I can change the reference automatically in code? (I will have the references base url saved in appsettings.json so we can change it without recompiling, because the base url is shared by all of the services, and the wsdl name at the end of it stays the same for each reference across environments.)
The reason I'm asking this as a new question is because, for one, there is limited help on the .net core implementation of service references with the wizard. Most solutions I've found are from 10-15 years ago and it took me a day to realize that those solutions don't apply. An example of a relevant solution is found here: Changing WCF Reference Url .Net Core, however, I don't understand the proposed solution at all.
In the solution, the OP says that adding the code var client = new GetUrlContractClient(new BasicHttpBinding(), new Endpoint("https://someurl/v3/GetUrl-Prod.svc"); solved the problem of updating the uri. My question is, where does this code live, and what is this client object? When I make a call to the API we're referencing, I create a new object asynchronously, there is no reference to some pre existing variable like client above... Did we already have to implement this somewhere and I'm just not seeing it? And what even is this GetUrlContractClient that is being called? I don't understand where the OP is using this if they set up the reference using the wizard.
[Edit] I should say that I also found that implementing the partial method "ConfigureEndpoint" to extend the auto generated code is the "preferred solution," as seen here load WCF service by environment in .net core project. When I try my best to do this for one of the references, it throws a security exception. If this is the way to do it, then I will devote my time to solving that error. However, this solution involves extending the ConfigureEndpoint for every reference, so I would have to do it upwards of 15 times, so it didn't seem to me that it would be the solution. Maybe this is what the OP for the referenced question was doing, but if so I do not see the connection. They seem to be completely different solutions.
It seems like this would be a relatively straight forward thing to lookup and solve with what we've already implemented, but I have had no luck. Anytime I find something, the answer is vague-ish like above and I don't see how it applies to my situation. How can I change the uri's for my web service references that are set up with the web service reference wizard?
Extending ConfigureEndpoint for each connected service works. The path cannot not include the ?wsdl at the end. The extension code (for one of my files) is below.
public partial class CreateOrderPortTypeClient
{
const string uriSuffix = "(last part of URI without ?wsdl)";
static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials)
{
EndpointCreator.SetServiceEndpointAddress(serviceEndpoint, uriSuffix);
}
}
I also added a class EndpointCreator which handles the base address, like so.
public class EndpointCreator
{
static string uriBase;
public static void GenerateBaseAddress(string uriBase)
{
EndpointCreator.uriBase = uriBase;
}
public static void SetServiceEndpointAddress(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, string uriSuffix)
{
serviceEndpoint.Address =
new System.ServiceModel.EndpointAddress(new System.Uri(uriBase + uriSuffix),
new System.ServiceModel.DnsEndpointIdentity(""));
}
}
I assigned the uriBase in startup by accessing the config. While I had to extend each one individually, its actually very manageable because this is a small thing to do when adding a new service through the wizard.

Creating Unit Tests in VS only allowed in Public Classes?

I am trying to clarify this notification message when trying to create a unit test for my method. The message clearly states that creating a unit test is only supported on a NON-Test project and within a public class OR a public method. I clearly have a public method but the class isn't. So is this just an incorrectly typed error message? Does it actually mean that you need to have both a public class and method?
Note: It works when I try this in a public class, just testing the notification.
Picture of notification message:
To test your class/method, you have to create another project - Testing project. Look at this as it has been another application that uses your classes.
So for example you have 3 projects (for sake of simplicity):
Domain - project with models and domain services
Console application - application that uses domain project
Test... let's say "Testing application" that tests Domain project.
So it points that class that you want to test MUST be available from test project. So it has to be public. You can also use attribute InternalsVisibleTo to make this class available for test project.
Your unit test project must be able to see (public visibility) the method you want to test in order to call it and execute it.
Here is a sample on a WinForm application:
You can clone the whole solution here:
Visual Studio solution on GitHub
Note that you can unit test private methods but it is not a good practice:
Solution downloadable here:
visual Studio solution on GitHub

Is it possible to execute an arbitrary class in C# with a Main method, similar to that in Java?

I've recently had to migrate to the C# world. Coming from the Java land, I could add a public static void main(String[] args) method to any class and select to run that class from Eclipse/Netbeans for any code/logic that I wanted to quickly test.
Is there an equivalent of the same capability in C#.Net/Visual Studio? I've tried doing that and the best I can do is to execute it from the command prompt via csc.exe. However, for some reason, it complains about not finding the relevant DLLs - it seems to expect to run that class in complete isolation without any dependency on "external code" (i.e., code residing in that VS project/solution where the class resides).
Reason for this capability: All project files are marked as class libraries and sometimes I just wish to check if a particular set of methods/data/logic will work as expected with the current code base. In Java, I'd quickly write it in the main method and execute that class to see how it goes prior to committing it to version control. However, there seems to be no easy way to trigger the execution of "my class" with all dependencies correctly handled by csc.exe
Current Solution: Add this testing code to the unit test project and select to execute that particular "test" so as to check if the idea seems to work fine (it may fire DB calls or webservice class etc., and not be purely a logical flow of computation). This seems to work fine and is my current way of doing things. I was wondering if the Main method was even possible/recommended.
Question: Is this even possible with C#/VS or not recommended?
Update: I can't add a console project just to achieve this since the addition of projects is tightly controlled by the source control team. Hence the question of the Main method 'hack' for quick and dirty checks/tests.
Your project type needs to be Console Application for it to "recognize" a Program.Main method, not Class Library. The intent is for a Class Library to be an encapsulated grouping of functionality that can only be accessed by a project that is set up to allow for user input. Those can be a Console Application, Web project (MVC/API), or Desktop (WPF).
If you just want to execute a test against the code within a Class Library project, you can also create a Unit Test project, add a reference and execute very explicit tests against the functionality you're looking to achieve.
You can find out the differences between the different project types by examining the .csproj files in your favorite text editor.
In Visual Studio go New->Project then select Console Application (in Windows\Classic Desktop in VS2015). This gives you a basic console application with...
static void Main(string[] args)
{
}
setup and ready to go. However for simply trying out code you may find this cumbersome (creating a new project and folder just to test code) and for testing code (that doesn't rely on existing libraries) you could use something like .NET Fiddle...
https://dotnetfiddle.net/
Where you can quickly create and test code there and run it via the browser.

How do I access Silverlight App.current.resources["x"] from a class library?

I am new to Silverlight. Arriving just in time to hear MS pronounce it dead on it's legs. :)
In our projected, we have a silverlight app hosted in a aspx page. There are configuration settings in the web.config (that is being transformed) contaning an environment variable to drive Webservice URLs in the View-Model classes.
All the view models are making use of a Common class library to establish the WS connection and wrap some often used WS calls. So when we build the WS, we need to know the environment value so we can divine the correct Service binding. Pretty much every part of this solution is in it's own project file.
Please exclude the crudeness of my illustraion.
web.config -> default.aspx -|-> app.xaml -> Xview.xaml -|-> XViewModel.cs -|-> ClassLib -|-> WCF Service.
-|-> is a project boundary.
Any help would be great. Even if it's just a vocabulary lesson.
Thanks in advance.
As i don't know the full architecture and how the library is used i don't know if this would work for you but possibly you can inject the instance. e.g. have a static property in you library which is used internally and set from the outside:
public static IApp CurrentApp { get; set; }
You probably you will want to declare an IApp interface in your class library which defines the needed functionality to not make it dependent on one specific application class. This interface then can be implemented by the application and the App instance can be assigned to the property.

Consuming a DLL in EXE

I had a discussion with friends last week about consuming the classes which are in DLL(.net DLL). I have a .net DLL which I need consume it in my Exe.
Normally,
I add the DLL in my solution and reference the DLL in my Exe
Create the object of the Class(which is in my DLL)
Start calling methods /function in the class from the object just created.
But finally decided that, We should use Reflection not the way we are doing. Reason is Loose coupling. One can change the functionality in the DLL and compile it. In such situations, You don't need to compile client code.
I have a question with this background.
Suppose, I have an a very simple application(Say console application) and I have two classes both are writtern to do different work.
class Program
{
static void Main()
{
//How do you create a object of the class A.
}
}
class A
{
string A = "I am from A";
public B b;
public A
{
b = new B();
}
}
class B
{
string B = "I am from B";
public B
{
}
public void Print()
{
Console.WriteLine(B);
}
}
How do you create the object of Class A when all the three classes the same exe and how you create the same object when Class A and class B in different DLL.
one answer for the sencond part of the question is use interface and use reflection.
Is reflection is it really required, or it is kind of programming standard.
What is the best practice to create an object of the class.
Interfaces provide a way to have loose coupling.
If you want to provide the ability to extend or replace the functionality after the fact without recompiling or even redeploying, then you're basically looking at a plug-in type architecture on top of the interface based loose coupling.
You could either use reflection to iterate and create an instance of the object but the other option is configuration/registration. For example, in your config file (or registry etc...) you could point to the file and class that implements that interface and use System.Activator to create it at runtime.
Example:
http://msdn.microsoft.com/en-us/library/ms972962.aspx
Another more robust option is MEF. It's a plug-in framework developed b the .net framework team.
Check out this link:
http://mef.codeplex.com/
From that link (reenforcing your question):
"Application requirements change frequently and software is constantly evolving. As a result, such applications often become monolithic making it difficult to add new functionality. The Managed Extensibility Framework (MEF) is a new library in .NET Framework 4 and Silverlight 4 that addresses this problem by simplifying the design of extensible applications and components. "
Hope that helps.

Categories

Resources