Hey I just recently learnt how to use extension methods and pretty excited to implement it in my current project.
My objective:
I want to check whether an entry exists in my table in a helper class, since I'm going to use it in multiple controllers to be able to determine which navigation links to show in my navbar:
My Issue:
I don't know how to access my dbcontext in my static helper class. My dbcontext controller takes an argument I don't know how to pass in my static class. I think creating a new dbcontext would solve my scope issue explained below but I don't see how I can pass the optional argument to my constructor.
It is currently configured in the Startup.cs class.
What I tried:
Passing the ApplicationDbContext as an argument. This works for a single method call in my controller, but when calling multiple extension methods (To check which game accounts the user has) I get a ObjectDisposedException.
ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'ApplicationDbContext'.
From what I understand it is a scope issue where the first method call disposes the context when it's done and I'm trying to use the same context in the next call? What can I do to work around that?
I tried reading this link Cannot access a disposed of object in ASP.NET Core when injecting DbContext but it didn't help me since it requires the ApplicationBuilder which is in the Startup.cs class.
Solution Update
I disposed the dbcontext after every method call because I put it into a variable. Instead, I call it directly on the passed context and it works:
Yeah, so, although the extensions are new and shiny to you, that doesn't mean you should use them for everything. First, extensions should have a logical connection to the type they're operating on. For example, if you have a string, something like ToUpper() makes sense as an extension because it modifies and returns a string. Something like what you're trying to do: just using the value of the reference to return a completely foreign type is a violation of the extension pattern.
Second, an extension should not interact with something like a database. In particular here, the static nature of an extension is completely incompatible with the concept of a EF context object. The only way you could even get it to work is to actually new up a context each time the extension is called, inside the extension. That's both a great way to screw up the EF object tracking stuff and a great way to leak memory.
Long and short, don't do this.
If you're just trying to factor out this code, you have better options. For example, you can actually just add methods directly to your context.
public class ApplicationDbContext : DbContext
{
...
public bool HasDota2Account(string id)
{
return Dota2Accounts.Any(m => m.ApplicationUserId == id);
}
}
Then, in your controller, you can simply do:
var hasDota2Account = context.HasDota2Account(User.Identity.GetUserId());
Never declare DbContext as static, it will cause all sorts of trouble, and not refresh the data, so you will be getting old data from a query. An option is to instantiate it inside the static method every time you use it, like this:
public static MyClass Example
{
public static bool MyStaticMethod(long id)
{
MyDBContext db = new MyDBContext();
//use db context now....
}
}
Related
Neither Lazy<T> nor Lazy<T, TMetadata> accept a Func<TSomething, T>. This seemingly makes it impossible to lazily create an object when the creation logic requires some extra context.
Here's a concocted example of what I'm trying to achieve:
private readonly Lazy<IDbConnection, IStatement> insertStatement =
new Lazy<IDbConnection, IStatement>(
conn => conn.CreateStatement(...));
public void Apply(IDbConnection connection)
{
this.insertStatement.GetValue(connection).Execute(...);
}
Here, an IDbConnection instance is required to create the IStatement housed by the Lazy instance. The assumption here is that once an IDbConnection is "known", it will remain the same. In other words, the IStatement does not need to change over time because the IDbConnection won't.
I've considered the alternative whereby my class takes an instance of IDbConnection in its constructor and creates the Lazy instances using a closure over that parameter. However, the reality is that obtaining the connection is an asynchronous operation and I'm having trouble seeing how I could make that happen before my dependent objects require it. This is a problem I intend pursuing, but still want to know the answer to this question...
Is there anything that facilitates scenarios whereby the factory used by Lazy can be passed some context that aids it in the creation of the object instance?
I can't comment, so, to try help you I need to post my comment like an answer.
If I understand correctly, you want to create a single Statement using a singleton Connection. If it's true what I'm thinking, maybe the code below can help you:
new Lazy<IStatement>(() => ConnectionSingleton.Instance.CreateStatement());
As you can see, you can delegate to other class the creation of the Statement
I am using .NET (MVC5, Web API etc). I understand constructor injection just about (fairly new to using it in anger).
I have a class with a method that has a dependency. I don't want to use constructor injection because then I will be creating the dependent object every time this class is instantiated (and most of the methods don't use this dependent object).
So I thought method injection sounded like it might be the thing. However I can't figure out how to do it (I am using Autofac).
So if my method is
void DoSomething(string x, int y)
and that method needs to use an implementation of IMyService, how do I do this without using the constructor injection?
The only method injection technique I have seen is one where effectively a method is called at instantiation. This doesn't seem to help my case, it still means that all instances create this dependency even if I am going to call a method that doesn't need it.
I'm sure it is something simple but I can't figure it out right now. Could you help me with an example please?
UPDATE
this is the crux of it. I like the idea of Lazy suggested by Jim and will try this. So is method injection as I suspected and if so I don't really understand the point of it - why use it instead of constructor injection?
public class MailService {
// lots of methods that don't need PlayerDataService
public void SendPlayersEmail() {
var service = new PlayerDataService();
var players = service.GetPlayers();
foreach(var player in players) {
SendEmail(player);
}
}
}
I don't want to use constructor injection because then I will be creating the dependent object every time this class is instantiated (and most of the methods don't use this dependent object).
There's the problem. Break that functionality out into a new class.
That is, at least in my experience, the best solution when a method does not fit into the rest of the class (or have dependencies that are not used anywhere else).
You should also consider that object allocation is pretty cheap, you need millions of allocations per second before the performance is hurt (unless you are using Ninject ;))
If the cost of instantiating your object during construction is an issue, you can wrap it in a Lazy<> to avoid unnecessary construction. This will cause your dependency to be constructed on the first call to the lazy's .Value.
I've been experimenting with the SimpleServiceLocator, and I like it quite a bit, but there's one thing that I'm really frustrated by--you can't use automatic constructor injection for singletons. To make matters worse, you can't even use automatic constructor injection for its dependencies. You have to create the singleton object, all it's dependencies, all its dependencies dependencies, etc. manually.
Why is SimpleServiceLocator designed this way?
Aren't singletons supposed to be just like regular instances except that, upon the first request for an instance, that instance is stored and reused instead of a new one being created each time? Why does SimpleServiceLocator require an instance to be provided during the registration process rather than just allow the instance to be created and stored on first request?
I get that the point of SimpleServiceLocator is to not have a lot of bells and whistles and be really easy for beginners to use, but it seems like it's just designed incorrectly, and that the method for registering a singleton should be identical to the method for registering a regular instance except that the method name should be RegisterSingle<T>() instead of Register<T>(). Is there a reason for the more complicated (and seemingly less convenient) design I'm just not getting?
Meanwhile, is there another (preferably free) IOC container I can use that let's me register objects in code similarly to the SimpleServiceLocator but does allow automatic contructor injection for singletons (or at least allows automatic constructor injection for the dependencies of the singleton)?
The RegisterSingle<T> method is just a fancy helper method just to make life easier. What you can do with RegisterSingle<T> can also be done with the Register<T> method. The web site gives examples of this. You can register a single instance using the Register<T> method as follows (it uses a closure):
var weapon = new Katana();
container.Register<IWeapon>(() => weapon);
When you look at the lifestyle management examples on the web site, you can see the following example for creating a thread static instance:
[ThreadStatic]
private static IWeapon weapon;
container.Register<IWeapon>(
() => return weapon ?? (weapon = new Katana()));
I think this is the power of simplify, because there is almost nothing you can't do with this pattern. What you are trying to achieve is a bit harder, I must admit this, but nothing really advanced IMO. Here is the code you need to solve your problem:
private static IWeapon weapon;
container.Register<IWeapon>(
() => weapon ?? (weapon = container.GetInstance<Katana>()));
The trick is here to store the instance in a static variable (just as with the thread static), but now you should not create the instance yourself by newing it up, but you delegate the creation to the Simple Service Locator. This works, because –as you know- the SimpleServiceLocator will do automatic constructor injection when a concrete type is requested.
I must admit that it is a shame that we need to do this trickery. It would be nice if the library could actually do this for us. For instance, I can imagine a RegisterSingle<T> overload being added that allows us to do the following:
container.RegisterSingle<IWeapon>(
() => container.GetInstance<Katana>());
Please let me know what you think of such an overload. I'm always interested in feedback to make the library better. This would certainly be a nice feature for the next release.
Update:
Since release 0.14 we can do the following:
container.RegisterSingle<IWeapon, Katana>();
It won't get any easier than this.
Cheers
A typical singleton implementation has a private constructor, so the container cannot "see" it, call it, or detect dependencies.
Perhaps you are referring to the lifetime management features of some IoC containers, where you can configure the container to always return the same single instance of a class.
This is not what singleton means. Although the container returns the same instance, nothing prevents you from instantiating an instance in code using new.
A singleton, on the other hand, can only ever be instantiated once from any source (once per thread in some implementations). It does not expose a public constructor, rather a static method such as:
public class MySingleton
{
// note: not a thread-safe implementation
static MySingleton instance;
static DependencyThing thing;
private MySingleton(DependencyThing thing)
{
MySingleton.thing = thing;
}
public static MySingleton GetMySingleton(DependencyThing thing)
{
if(instance == null) instance = new MySingleton(thing);
return instance;
}
}
As you can see, you can't call new MySingleton() from outside the class itself. To "instantiate" the a MySingleton, you have to call MySingleton.GetMySingleton(thing). This call returns the sole instance or creates and then returns it.
SimpleServiceLocator has no way of knowing how to create this object, or from where to detect its dependencies.
This ability could be added if the API exposed something like
public void Register<T>(Expression<Func<T>> staticFactoryMethod)…
…in which case you could call Register(() => MySingleton.GetMySingleton());, but this would only work without parameters. There would have to be more overloads:
public void Register<T, TParam1>(Expression<Func<TParam1, T>> staticFactoryMethod)…
public void Register<T, TParam1, TParam2>(Expression<Func<TParam1, TParam2, T>> staticFactoryMethod)…
…so that the container would know what dependencies to instantiate and pass to the specified factory method.
All that said, it doesn't really make sense to have dependency injection with a singleton. Each subsequent call to GetMySingleton would have to ignore the arguments or alter the state of the singleton, which is almost certainly a very bad idea.
public MyClass(int someUniqueID)
{
using(//Session logic)
{
var databaseVersionOfMyClass = session.CreateCriteria(/*criteria*/)
.UniqueResult<MyClass>();
//Load logic
}
}
The code sample above is my current direction, although I've reached a point where I need a bit of a sanity check.
With NHibernate(I'm green in this area), is it common or best practice to instantiate an object from a database within the class constructor? The alternative I believe, would be to have a static method that returns the object from the database.
I've also come across a relevent question regarding constructors vs factory methods, however I don't believe this implementation fits the factory methodology.
To add an additional question onto the above, if instantiation within the constructor is the way to go, I've always used some sort of Load() method in the past. Either a specific private method that literally matches properties from the returned db object to the new class, or via a generic reflective method that assumes property names will match up. I'm curious if there is another way to "load" an object that I've missed.
I do not like this approach.
IMHO , it is better to implement some kind of repository which retrieves instances of persisted classes for you.
As an alternative, you could also follow the ActiveRecord approach, where you could have a static 'Load' method inside your class, and an instance method 'Save' for instance. (Take a look at Castle ActiveRecord).
But, for me, I prefer the Repository approach.
I'm still struggling a bit with OOP concepts and dependency injection so bear with me.
I have generated my Linq2Sql model with a User table and now I would like to be able to send a confirmation email to this user so I created a partial class file for my User object and I felt it was natural to add a SendConfirmationEmail() method to the User class. This method will use a MailService to send the actual email and I would like to use dependency injection to pass in the service so I created a constructor overload on the User object like this
public User(IMailService service) : this()
{
_service = service;
}
The SendConfirmationEmail method would look like this
public void SendConfirmationEmail()
{
_service.SendMail(params...);
}
I realize this is a kind of poor mans dependency injection and I hope to switch to a dependency injection framework later as I am getting more grips on this.
The problem for me is that I need to make a reference from my model dll to my service dll which does not seem right and because I am unsure of how nice my linq2sql generated entities plays with Dependency injection frameworks and OOP concepts (I think ninject looks most promising).
I was hoping someone with a bit more experience than me could tell I'm if I am going in the right direction with this. I know I can make it work but I would like to educate my self in doing it in the correct way in the same step.
I personally would change some things in your architecture:
I don't think that SendConfirmationEmail should be a method on your User object. But should be a method on another object with the user as a parameter. (this also better seperates your Dal from the other logic.
Second in this method use something like this:
Services.Get<IMailService>().SendMail(params ...);
You can implement Services as the folowin (just an example):
public class Services
{
protected static Dictionary<Type, object> services = new Dictionary<Type, object>();
private Services()
{
}
static Services()
{
// hard coded implementations...
services.Add(typeof(IMailService), new DefaultMailServiceImplementation());
}
public static T Get<T>() where T : class
{
Type requestedType = typeof(T);
return services[requestedType] as T;
}
}
By using a "Services"-class (or call it what you like) you add an additional layer between the IOC-framework and your code which makes it easy to change IOC-frameworks. Just change the implementation in the Get method to use one. You can also use a hardcoded temporary solution (until you use an IOC-framework) in the static constructor (like I did in the above example).
The problem with that approach is that much of the time the entity is going to come from the LINQ-to-SQL back-end, and so isn't going to use your constructor (LINQ-to-SQL creates objects in its own way; you cannot force LINQ-to-SQL to use your constructor) - so this would only be useful for the (few) objects you create yourself. Data-binding (etc) will also commonly use the parameterless constructor by default.
I wonder if this wouldn't work better as a utility method that accepts the service, or obtains the service itself via a factory / singleton.
I think you're ok doing this, but you might want to do two additional things to protect yourself from future cross-layer dependency problems:
Create an interface for your User
object. You should do this because
not doing so will mean that
everything that consumes this
business object will have to
reference the LINQ dlls
unnecessarily.
Move your dependency injection from
the constructor into a property.
You do this because constructor
injection tends to limit your
ability to dynamically create your
object. Doing this, though poses a
problem, since you would have to
implement a lot of null checking
code for _service. You can fix this
by creating an "empty"
implementation of IMailService and
make it the default value for
_service.