I have a static variable inside of my main project (mvc), I am wanting to be able to pass/use that variable in my other project (asp.net core 5.0 web api) project. I was reading up on how you can perform this task, one of the ways is using a static variable which I have. I read this post and one of the solutions mentions you can call that static variable from the first project into the other project by calling the namespace of that first project in the first project. However, when I do so it does not let me it says it does not exist. Is there a way to be able to do this?
On the post their example was:
using System.Windows.Forms;
namespace Demo1
{
public class Sample1
{
public static string x = "initial value of 'x";
public void sampleFn1() {x = "value of 'x set in function";}
}
}
namespace Demo2
{
public class Sample2
{
public void sampleFn2(){MessageBox.Show(Demo1.Sample1.x);}
}
}
For me, Project 1 is CustomerApp and Project 2 is Service.Api:
namespace CustomerApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public static Guid uniqueId = Guid.NewGuid();
}
}
Then in my ServiceApi I tried performing the same as the example from the post, but when I call the namespace CustomerApp it does not give me any options to reference it to the other project. Is there a specific using I need to use in order to replicate the example from the post?
namespace Service.API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly ILogger<ValuesController> _logger;
public ValuesController(ILogger<ValuesController> logger)
{
_logger = logger;
}
// GET: api/<ValuesController>
[HttpGet]
[Route("sample")]
public ActionResult Get()
{
_logger.LogInformation("Target method invoked.....{#CorrelationId}", CustomerApp.); // here I am trying to perform CustomerApp.Controllers.HomeController.uniqueId.ToString()
}
}
}
You will want to make sure that the static variable is defined in a Class Library project, and that the Web project has a reference to the Class Library project.
The way your code is currently constructed, it looks like both projects are web projects (your first project mentions the HomeController). As much as possible, avoid this type of co-mingling. Move business logic into the class library, and keep the web logic in the web project.
I think you forgot to add the project reference to destination project where you want to use the variable ,
Add reference like this :
right-click on your destination project and select Add > Project Reference
and in final choose the variable project
this will help you
first, if you haven't, add it to the HomeController class (using CustomerApp.Controllers.HomeController;). Your own example does not match the example you reference. In the first example, a static variable is used between two different classes in the same namespaces, but in your example you are trying to operate between different namespaces and different classes.
So if your service is inside your main project you should add.
then you can use it as below.
public ActionResult Get()
{
_logger.LogInformation("Target method invoked.....{#CorrelationId}", HomeController.uniqueId.ToString());
}
Related
I am attempting to verify that a user is authorized via a custom policy. I followed the tutorial at Ode To Code to add this functionality to my controller. From within Visual Studio, the code appears to be correct and utilizing a known overload.
Notice that it says that the overload is an "extension". I didn't take much notice of this until I spent 5 hours today trying to solve the following error:
As you can see, it would appear that the overload I'm attempting to use isn't being utilized. Am I doing something wrong here? Is there something special I have to do to include these extended methods? I've attempted cleaning and rebuilding the solution but this hasn't solved the problem.
While you've defined the field for IAuthorizationSerivce, you haven't provided any way for that to be set. You need to define a constructor for the LRController that takes a single parameter of IAuthorizationService, and assign that to the field.
I think there was a definition of that constructor in the tutorial.
Please note the name change: such as the global variable name for IAuthorizationService _authorization has been prefixed with an underscore. Obviously not required, but as a good rule of thumb/good coding standard, IMO. :-)
public class LRController : Controller
{
private readonly IAuthorizationService _authorization;
// you're missing this constructor & this pattern is known as Constructor Dependency Injection
public LRController(IAuthorizationService authorization)
{
_authorization = authorization;
}
public async Task<RedirectToActionResult> Index()
{
var superAdmin = await _authorization.AuthorizeAsync(User, "IsLucky");
//rest of your code here
}
}
EDIT
Additionally, if you wanted/needed to inject other interfaces into this controller, you would add it to that LRController constructor. Would look something like this:
public class LRController : Controller
{
private readonly IAuthorizationService _authorization;
private readonly IOtherService _otherService;
public LRController(IAuthorizationService authorization, IOtherService otherService)
{
_authorization = authorization;
_otherService = otherService;
}
public async Task<RedirectToActionResult> Index()
{
var superAdmin = await _authorization.AuthorizeAsync(User, "IsLucky");
}
public async Task Foo()
{
await _otherService.Bar();
}
}
Update:
This is an mvc plugin project, using MEF to get the controllers and actions at run time. http://www.fidelitydesign.net/?p=104
I added a new project and in its class I added an export of a type that is already being composed.
[Export(typeof(IController)), ExportMetadata("Name", "Clocks")]
public class ClocksController : Controller
{
public XmlActionResult Index()
{
var p = DeviceLogic.GetUnassigned;
}
[Import(typeof(DeviceLogic))]
DeviceLogic DeviceLogic { get; set; }
}
This gets composed in another project:
[Export]
public class ImportControllerFactory : DefaultControllerFactory
{
[ImportMany]
private IEnumerable<PartFactory<IController, IControllerMetadata>> ControllerFactories;
}
Application Start
[ImportMany]
private IEnumerable<ImportControllerFactory> ControllerFactories;
Controller factories is null, until I actually compose the parts
container.ComposeParts(this);
thats working fine, so I decided to try and emulate this to get devicelogic to appear in the project im having trouble with.
I created an emptry interface (IEmpty) for testing and tried this:
[Export(typeof(IEmpty))]
public class RequestProcessor : IEmpty
{
[Import(typeof(DeviceLogic))]
DeviceLogic DeviceLogic { get; set; }
}
and in my applciation start added
[ImportMany]
private IEnumerable<IEmpty> TestMef;
This is filled with the one instance after composition, so this seems to have worked. My question is does anyone have any suggestions as to why devicelogic is null in requestprocessor but not in clocksController.
You need to call MEF's SatisfyImportsOnce method after your instantiation :
YourMEFContainter.SatisfyImportsOnce(dataTransfer)
I have a class library that I added another class to that no matter what I try it will not be available in the project that I am referencing the library from. I have no problem with the original class I created in this library referencing and using.
I have tried all of the below:
Cleaning the project solution
Save and rebuild both the debug and release
Closing the project and reopening
Steps one through three on the library project I'm tyring to reference
In the project that I want to reference the library from I have tried loading the .dll form the bin/release folded, and the main library project .dll in the obj/release folder. Neater have made a difference because I still cannot get to the new class I added to the library. I am referencing the DotNetOpenAuth_Library.dll from the release folded in the bin.
If this makes a difference I'm using VS 2012 Express for Web that I downloaded last week.
The class I added to my library that has no build errors is:
namespace DotNetOpenAuth_Library
{
class EmbeddedResourceUrlService : IEmbeddedResourceRetrieval
{
private static string pathFormat = "{0}/Resource/GetWebResourceUrl? assemblyName= {1}&typeName={2}&resourceName={3}";
//private static string pathFormat = "{0}/Resource/GetWebResourceUrl";
public Uri GetWebResourceUrl(Type someTypeInResourceAssembly, string manifestResourceName)
{
if (manifestResourceName.Contains("http"))
{
return new Uri(manifestResourceName);
}
else
{
var assembly = someTypeInResourceAssembly.Assembly;
// HACK
string completeUrl = HttpContext.Current.Request.Url.ToString();
string host = completeUrl.Substring(0,
completeUrl.IndexOf(HttpContext.Current.Request.Url.AbsolutePath));
var path = string.Format(pathFormat,
host,
HttpUtility.UrlEncode(assembly.FullName),
HttpUtility.UrlEncode(someTypeInResourceAssembly.ToString()),
HttpUtility.UrlEncode(manifestResourceName));
return new Uri(path);
}
}
}
}
Put public in front of the class definition. If the class is marked internal1 it can only be accessed by other classes within the same assembly2.
namespace DotNetOpenAuth_Library
{
public class EmbeddedResourceUrlService : IEmbeddedResourceRetrieval
{
//(snip)
}
}
Here is a MSDN link explaining access modifiers.
1: If you do not put a modifier in front of the class it will default to internal.
2: unless you mark the other assembly a friend assembly
It looks to me like the problem is just the lack of an access modifier. By default the c# compiler treats classes as internal. It should work if you change the declaration to
public class EmbeddedResourceUrlService : IEmbeddedResourceRetrieval
The class EmbeddedResourceUrlService is private, use public modifier
namespace DotNetOpenAuth_Library
{
// make class public
public class EmbeddedResourceUrlService : IEmbeddedResourceRetrieval
{
private static string pathFormat = "{0}/Resource/GetWebResourceUrl? assemblyName= {1}&typeName={2}&resourceName={3}";
//private static string pathFormat = "{0}/Resource/GetWebResourceUrl";
public Uri GetWebResourceUrl(Type someTypeInResourceAssembly, string manifestResourceName)
{
if (manifestResourceName.Contains("http"))
{
return new Uri(manifestResourceName);
}
else
{
var assembly = someTypeInResourceAssembly.Assembly;
// HACK
string completeUrl = HttpContext.Current.Request.Url.ToString();
string host = completeUrl.Substring(0,
completeUrl.IndexOf(HttpContext.Current.Request.Url.AbsolutePath));
var path = string.Format(pathFormat,
host,
HttpUtility.UrlEncode(assembly.FullName),
HttpUtility.UrlEncode(someTypeInResourceAssembly.ToString()),
HttpUtility.UrlEncode(manifestResourceName));
return new Uri(path);
}
}
}
}
even if then the class does not shows up (has happended to a couple time)
clean solution
delete all bin folder from both project
rebuilt all
and error wont be there
I'm trying to implement the the Microsoft Extensibility Framework (MEF) into a sample MVC-based web app. I'm using the SimpleCalculator example solution on the MEF Overview page. My goal is an application that can dynamically load a DLL extension from another project in order to extend the capabilities of the Model, essentially I want the MVC-Application to be a framework for other extensions to plug-into. First my setup:
Project 1 (MVC-Application, MEF Component Host):
I decorate the elements in my Model as follows:
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
namespace ExpressionParserPOC.Models
{
public class ExpressionModel
{
private CompositionContainer _container;
[ImportMany]
IEnumerable<Lazy<IExtensions,IExtensionName>> extensions { get; set; }
public ExpressionModel()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog("C:\\local_visual_studio\\ExpressionParserPOC\\ExpressionParserPOC\\Extensions"));
//Create the CompositionContainer with the parts in the catalog
_container = new CompositionContainer(catalog);
_container.ComposeParts(_container);
//TEST: Can we access the extensions?
if (extensions != null)//<--NULL WHEN CONSTRUCTOR IS CALLED WHY? Expected GetMatrix() Function from DLL to be exposed
{
foreach (Lazy<IExtensions, IExtensionName> i in extensions)
{
Lazy<IExtensions, IExtensionName> foo = i;
}
}
}
}
public interface IExtensions
{
double[][] GetMatrix(string matrix);
}
public interface IExtensionName
{
Char Symbol { get; }
}
}
To test right now, I'm just calling the constructor for the Model from the Controller:
namespace ExpressionParserPOC.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Enter an Expression for Octave to evaluate";
//Instantiate an ExpressionModel composed of extensible parts
var model = new ExpressionModel();
return View(model);
}
}
}
Project 2 (DLL Project, MEF Component):
//PROJECT BUILD OUTPUTS TO THE EXTENSIONS DIRECTORY IN PROJECT 1 ABOVE
using System.ComponentModel.Composition;
namespace MyExtensions
{
//Project 1 already added as a reference
[Export(typeof(ExpressionParserPOC.Models.IExtensions))]
[ExportMetadata("Symbol", 'o')]
public class Octave : MyExtensions.IExtensions
{
//Other class properties, constructors, functions, etc.
#region FUNCTIONS
public double[][] GetMatrix(string matrix)
{
double[][] mat = new double[][];
//Do Stuff
return mat;
}
#endregion
}
public interface IExtensions : ExpressionParserPOC.Models.IExtensions
{
}
}
Problem is that the the extensions List in the host MVC application project never gets filled when I call the Model constructor from the Controller in that same project. I'm new to MEF development and am not sure what I'm doing wrong, is there something extra I need to consider since I'm working with an MVC application? Why won't the Project 1 extensions list get filled? Are my interface definitions wrong? The sample calculator application is a simple command line project and that seems to work fine, the only difference I see is that the external DLL project is in the same solution space, whereas with my example the solution spaces are independent.
A trivial mistake you have there in the ExpressionModel constructor. You are composing the container itself :)
_container.ComposeParts(_container);
The problem should be apparent instantly, because if the composition of the ExpressionModel actually ever happened, even if no extensions were discovered, the extensions property would be initialized with 0 items, but it wouldn't be null.
You need to compose the current model instance like this:
_container.ComposeParts(this);
Everything else seems to be alright and should be working fine after this correction.
I am working through the book Professional ASP.NET MVC 2 and I am trying to get the unit testing in chapter 1 to work correctly; howver, I am getting some very strange errors.
There are two projects in the solution: NerdDinner, and NerdDinner.Tests.
In the NerdDinner Project I have the following interface:
IDinnerRepository.cs
//...
namespace NerdDinner.Models
{
interface IDinnerRepository
{
//...
}
}
Also in the NerdDinner project, I have the following class:
//...
using NerdDinner.Models;
//...
namespace NerdDinner.Controllers
{
public class DinnersController : Controller
{
IDinnerRepository dinnerRepository;
// Default constructor
public DinnersController() : this(new DinnerRepository()){} // DinnerRepository is another concrete implementation of IDinnerRepository
//Test constructor
public DinnersController(IDinnerRepository repository) {
dinnerRepository = repository;
}
}
}
In the NerdDinner.Tests project, I have the following concrete implementation of IDinnerRepository:
//...
using NerdDinner.Models;
//...
namespace NerdDinner.Tests.Fakes
{
class FakeDinnerRepository : IDinnerRepository
{
//...
public FakeDinnerRepository(List<Dinner> dinners)
{
//...
}
//...
}
}
Now for the actual unit test (in NerdDinner.Tests)
using NerdDinner.Controllers;
//...
using NerdDinner.Models;
using NerdDinner.Tests.Fakes;
namespace NerdDinner.Tests
{
[TestClass]
public class DinnersControllerTest
{
List<Dinner> CreateTestDinners()
{
//...
}
DinnersController CreateDinnersController()
{
return new DinnersController(new FakeDinnerRepository(CreateTestDinners()));
}
}
}
And now for the actual problem:
In the method CreateDinnersController in the class DinnerControllerClass, I am getting the following error:
DinnersController.DinnersController(NerdDinner.Models.IDinnerRepository repository) (+ 1 overload(s))
Error:
The best overloaded method match for 'NerdDinner.Controllers.DinnersController.DinnersController(NerdDinner.Models.IDinnerRepository)' has some invalid arguments.
It gives me the option to create a constructor stub in DinnersController. It generates the following code:
private global::NerdDinner.Tests.Fakes.FakeDinnerRepository repository;
//...
public DinnersController(global::NerdDinner.Tests.Fakes.FakeDinnerRepository repository)
{
// TODO: Complete member initialization
this.repository = repository;
}
Even after generating that code, I still get the same error. But why should I even need that code anyway? As far as I can tell, I am doing everything correctly.
Can anybody help me figure out what is going on here?
Edit
The generated code is giving the following error:
The type or namespace 'Tests' does not exist in the namespace 'NerdDinner' (are you missing any assembly reference?)
From what you've shown the IDinnerRepository interface is not public meaning that it is not visible from your unit test. I would recommend you making it public as I suspect you have two different interfaces : one defined in the unit test and one in your project which conflict. Also I would recommend you to avoid relying on Visual Studio generate all the crap reflection code in order to test private and internal members.
The last error you're getting is due to there being no reference from the production code to the test code - but that's appropriate. You don't want that extra constructor.
Instead, you need to find out why the existing constructor taking an IDinnerRepository isn't being used. Are you sure you only have one interface called IDinnerRepository? If you go to the FakeDinnerRepository source, go to the declaration, put the cursor in IDinnerRepository and hit F12 (go to definition) does it go to the right place?
If you add a new member to IDinnerRepository (just for the sake of testing: void Foo(); would be fine) does it cause both the production and fake implementation to fail to compile?