I will insert logs from exception handler and i've action for post logs. How can I call my service action properly?
Is creating instance everytime correct?
public class CustomExceptionHandler : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
var exceptionModel = new System_Logs() { Date = DateTime.Now, Request = actionExecutedContext.Request.RequestUri.AbsoluteUri, Response = actionExecutedContext.Response.Content.ToString()};
System_LogsController controller = new System_LogsController();
controller.PostSystem_Logs(exceptionModel);
base.OnException(actionExecutedContext);
}
}
You should create a logging service class (not a controller class) that will handle logging. If you are using dependency injection, for custom filter attributes use property injection using the [Dependency] annotation/decorator to the property. This logging service will be initialized via injection container. You can search in SO for IoC (e.g Unity, autofac, ninject, etc) to help you get started. It's worth knowing this IoC and dependency injection principles as it can apply both on the server side and in the client side(javascript development).
To elaborate on what you currently have. Your code above will look like something like:
public class CustomExceptionHandler : ExceptionFilterAttribute
{
[Dependency]
public ILoggingService LoggingService { get; set; }
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
var exceptionModel = new System_Logs() { Date = DateTime.Now, Request = actionExecutedContext.Request.RequestUri.AbsoluteUri, Response = actionExecutedContext.Response.Content.ToString()};
LoggingService.PostSystemLogs(exceptionModel);
base.OnException(actionExecutedContext);
}
}
Related
Trying to use EF 6 code first with a WCF service, but have run into the following runtime error:
The default DbConfiguration instance was used by the Entity Framework
before the 'MyConfiguration' type was discovered. An instance of
'MyConfiguration' must be set at application start before using
any Entity Framework features or must be registered in the
application's config file. See
http://go.microsoft.com/fwlink/?LinkId=260883 for more information.
This error is thrown when trying to instantiate the following DbContext inside a service call:
[DbConfigurationType(typeof(MyConfiguration))]
public partial class MyContext : DbContext
{
public MyContext()
: base("name=MyContext")
{
}
}
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
SetExecutionStrategy(MySqlProviderInvariantName.ProviderName, () => new MySqlExecutionStrategy());
SetDefaultConnectionFactory(new MySqlConnectionFactory());
AddDependencyResolver(new MySqlDependencyResolver());
}
}
This WCF service has other DbContexts that are used before this class is even accessed, so the error message makes perfect sense. The question is where should the configuration be set?
Create a constructor on MyContext as follows:
public MyContext(DbConnection dbConnection, bool contextOwnsConnection)
: base(dbConnection, contextOwnsConnection)
{
}
Then supply a MySqlConnection manually:
var connection = new MySqlConnection(connectionString);
connection.Open();
var context = new MyContext(connection, true);
I'm using Windsor to manage IoC for my controllers in a WebAPI project. I've got a DependencyResolver working nicely to resolve controller dependencies, but now I'm looking to inject dependencies into a custom action filter I'm using to manage authentication.
I've looked into using a custom ActionInvoker but it's not clear from the interface that WebAPI is using how I would go about resolving property dependencies on the custom action filter attribute before it executes. Anyone have a good example of how to do this in the MVC 4 RC?
EDIT: I'm aware you can't do constructor injection on filters, because they're attributes and therefore instantiated by the .NET framework - but I'm hoping there's some point in the execution lifecycle that happens AFTER the filter is instantiated but BEFORE it gets executed, where I could run some custom code to enumerate across the filters' public properties and inject the necessary services.
Action filters are attributes. In .NET attribute the instantiation process is managed by the .NET runtime and you don't have control over it. So one possibility is to use Poor Man's Dependency Injection which I would personally advice you against.
Another possibility is to use a marker attribute:
public class MyActionFilterAttribute : Attribute
{
}
and then have the action filter using constructor injection:
public class MyActionFilter : ActionFilterAttribute
{
private readonly IFoo _foo;
public MyActionFilter(IFoo foo)
{
_foo = foo;
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ActionDescriptor.GetCustomAttributes<MyActionFilterAttribute>().Any())
{
// The action is decorated with the marker attribute =>
// do something with _foo
}
}
}
and then register it as a global action filter in Application_Start:
IFoo foo = ....
GlobalConfiguration.Configuration.Filters.Add(new MyActionFilter(foo));
I had the same problem, but decided to go for the ServiceLocator (DependencyResolver.GetService) for this, as its in the framework it seems to me to be a valid approach
public class RequiresSessionAttribute :
ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var sessionService =
(ISessionService) actionContext
.ControllerContext.Configuration.DependencyResolver
.GetService(typeof (ISessionService));
var sessionId = HttpUtility
.ParseQueryString(actionContext.Request.RequestUri.Query)
.Get("sessionId");
if (sessionId == null
|| !sessionService.IsValid(sessionId))
throw new SessionException();
base.OnActionExecuting(actionContext);
}
}
and here is a test for this attribute, bit of a pain but possible
public class requires_sessionId
{
[Fact]
void can_call_action_with_session_id()
{
var context = GetContext("http://example.com/?sessionId=blaa");
var sut = new RequiresSessionAttribute();
Assert.DoesNotThrow(
() => sut.OnActionExecuting(context));
}
[Fact]
void can_not_call_action_without_session_id()
{
var context = GetContext("http://example.com/");
var sut = new RequiresSessionAttribute();
Assert.Throws<SessionException>(
() => sut.OnActionExecuting(context));
}
HttpActionContext GetContext(string url)
{
var sessionServiceMock = new Mock<ISessionService>();
sessionServiceMock
.Setup(x => x.IsValid(It.IsAny<string>()))
.Returns(true);
var dependancyResolverMock = new Mock<IDependencyResolver>();
dependancyResolverMock
.Setup(x => x.GetService(It.IsAny<Type>()))
.Returns(sessionServiceMock.Object);
var config = new HttpConfiguration
{
DependencyResolver = dependancyResolverMock.Object
};
var controllerContext = new HttpControllerContext
{
Configuration = config,
Request = new HttpRequestMessage(
HttpMethod.Get,
url)
};
return
new HttpActionContext
{
ControllerContext = controllerContext,
};
}
}
I am having trouble getting Castle Dynamic Proxy to intercept methods that are explicit interface implementations. I read here http://kozmic.pl/category/dynamicproxy/ that it should be possible to do this.
Here are my classes;
internal interface IDomainInterface
{
string DomainMethod();
}
public class DomainClass : IDomainInterface
{
string IDomainInterface.DomainMethod()
{
return "not intercepted";
}
}
Here is my interceptor class;
public class DomainClassInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (invocation.Method.Name == "DomainMethod")
invocation.ReturnValue = "intercepted";
else
invocation.Proceed();
}
}
And here is my test (which fails);
[TestClass]
public void can_intercept_explicit_interface_implementation()
{
// Create proxy
var generator = new ProxyGenerator();
var interceptor = new DomainClassInterceptor();
var proxy = (IDomainInterface)generator.CreateClassProxy(typeof(DomainClass), interceptor);
// Invoke proxy method
var result = proxy.DomainMethod();
// Check method was intercepted -- fails
Assert.AreEqual("intercepted", result);
}
In addition to not being able to intercept the explicit interface implementation, it also seems that I am not receiving a notification of a non-proxyable member.
Here is my proxy generation hook (which acts as a spy);
public class DomainClassProxyGenerationHook : IProxyGenerationHook
{
public int NonProxyableCount;
public void MethodsInspected() {}
public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo)
{
NonProxyableCount++;
}
public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
{
return true;
}
}
Here is my test (which again fails);
[TestMethod]
public void receive_notification_of_nonproxyable_explicit_interface_implementation()
{
// Create proxy with generation hook
var hook = new DomainClassProxyGenerationHook();
var options = new ProxyGenerationOptions(hook);
var generator = new ProxyGenerator();
var interceptor = new DomainClassInterceptor();
var proxy = (IDomainInterface)generator.CreateClassProxy(typeof(DomainClass), options, interceptor);
// Check that non-proxyable member notification was received -- fails
Assert.IsTrue(hook.NonProxyableCount > 0);
}
Has anyone had success in getting DP to intercept explicit interface implementations? If so, how?
You are creating a class proxy. Class proxy only intercepts virtual methods on the class, and an explicit implementation of an interface method in C# by definition is not virtual (since it's private).
If you want to intercept methods on the interface you need to explicitly tell DynamicProxy about it
var proxy = (IDomainInterface)generator.CreateClassProxy(typeof(DomainClass), new Type[] { typeof(IDomainInterface) }, interceptor);
Also your interface is marked as internal so made sure it's public for DynamicProxy (either make the interface public or add InternalsVisibleToAttribute).
With that your first test will pass, and the method will be intercepted.
I'm using EF4.1 with MVC3 and I need an override to prevent EF from creating a db if it doesn't exist. Instead of creating a new db I would like to catch the error and report that the initial catalog (the database name) is invalid in the connect string.
However, during development I would like to allow for updates for new classes/properties to create according tables/cols in the database.
Is there a best practice or pattern here?
In my application i am completly disable context initializer and handle database mapping and schema manually.
For example :
public class AppDbContext : DbContext
{
public IDbSet<Account> Accounts { get; set; }
public AppDbContext() : base("connection_string")
{
Database.SetInitializer<AppDbContext>(null); // Important! Dont use entity framework initializer !important
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
/* Register custom mapping class */
modelBuilder.Configurations.Add(new AccountMapper());
base.OnModelCreating(modelBuilder);
}
}
And custom mapping :
public class AccountMapper : EntityTypeConfiguration<Account>
{
/// <summary>
/// Employee entity mapper
/// </summary>
public AccountMapper()
{
ToTable("accounts");
HasKey(x => x.Id);
...
}
}
I would suggest looking into the EF database initializer, specifically the IDatabaseInitializer interface.
If you just want it to stop creating the database when it doesn't exist, then just set the Initializer to null. But if you want to log the event or something along those lines then simply create your own IDatabaseInitializer - it's not hard.
You can then set the initializer Application_Start in your global.asax.cs like so:
Database.SetInitializer(new YourCustomInitializer());
As a bonus, here's an example IDatabaseInitializer that I use to run database migrations (using FluentMigrator)... it's extremely handy if I do say so myself!
public class MigrationsDbContextInitializer : IDatabaseInitializer<YourDbContext>
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(MigrationsDbContextInitializer));
public void InitializeDatabase(YourDbContext context)
{
var announcer = new BaseAnnouncer(x => Logger.Info(x));
var runnerContext = new RunnerContext(announcer)
{
Database = "sqlserver2008",
Connection = context.Database.Connection.ConnectionString,
Target = "YourEntitiesNamespace",
PreviewOnly = false,
Task = "migrate"
};
new TaskExecutor(runnerContext).Execute();
}
}
Can anyone tell me how to find available agent containers through java code? I am using the JADE agent framework and I have figured out how to create new containers but not find existing containers (so that agents can be deployed in them).
There are two ways of doing this, depending on whether you want to receive the information via an ongoing service or the current snapshot in a message.
To get a snapshot of the IDs of the currently available agent containers, send a Request message to the Agent Management Service (AMS) and wait for its reply. Using the JADE Management Ontology and the QueryPlatformLocationsAction term, the sending and receiving methods would be:
private void queryAMS() throws CodecException, OntologyException {
QueryPlatformLocationsAction query = new QueryPlatformLocationsAction();
Action action = new Action(myAgent.getAID(), query);
ACLMessage message = new ACLMessage(ACLMessage.REQUEST);
message.addReceiver(myAgent.getAMS());
message.setLanguage(FIPANames.ContentLanguage.FIPA_SL);
message.setOntology(JADEManagementOntology.getInstance().getName());
myAgent.getContentManager().fillContent(message, action);
myAgent.send(message);
}
private void listenForAMSReply() throws UngroundedException, CodecException,
OntologyException {
ACLMessage receivedMessage = myAgent.blockingReceive(MessageTemplate
.MatchSender(myAgent.getAMS()));
ContentElement content = myAgent.getContentManager().extractContent(
receivedMessage);
// received message is a Result object, whose Value field is a List of
// ContainerIDs
Result result = (Result) content;
List listOfPlatforms = (List) result.getValue();
// use it
Iterator iter = listOfPlatforms.iterator();
while (iter.hasNext()) {
ContainerID next = (ContainerID) iter.next();
System.out.println(next.getID());
}
}
To get this information as an ongoing service, and to receive the ContainerID of each container as it registers with the AMS, create a Behaviour that extends the AMSSubscriber. Register a handler for the AddedContainer event and you will be able to access the ContainerID of the newly available container:
public class AMSListenerBehaviour extends AMSSubscriber {
#Override
public void installHandlers(Map handlersTable) {
handlersTable.put(AddedContainer.NAME, addedContainerHandler);
}
public final class AddedContainerHandler implements EventHandler {
#Override
public void handle(Event ev) {
AddedContainer event = (AddedContainer) ev;
ContainerID addedContainer = event.getContainer();
System.out.println(addedContainer.getID());
}
Hope this helps,
Russ