View Full Version : what are you injecting with Spring.Net?
SecretSquirrel123
04-08-2005, 06:38 PM
Hi,
What are you using Spring.Net for? I see that it can be used to inject mock objects, security, logging, service location. Wondering what people are using it for in the .NET world.
It seems to me that Spring.Net is basically an abstract factory implementation. I can understand the utility of this pattern. But I am not sure where to implement with Spring.Net rather than thru regular c# code?
Thanks,
Jon Paugh
JasonGerard
04-08-2005, 06:48 PM
What are you using Spring.Net for? I see that it can be used to inject mock objects, security, logging, service location. Wondering what people are using it for in the .NET world.
It seems to me that Spring.Net is basically an abstract factory implementation. I can understand the utility of this pattern. But I am not sure where to implement with Spring.Net rather than thru regular c# code?
You're exactly right, the IoC portion of Spring.Net is a glorified factory.
Anyplace you would or could use a factory you could use Spring. Of course, you could write the factory yourself, or, you could let Spring do everything for you plus get all the goodies like life cycle management and easier configuration.
I'm currently working on a basic Rules Engine that will execute code written in any .NET language. I have an IRuleCompiler interface that I program against. I let Spring populate this with whatever impl I want without tying ANY of my code to the implementation so I can switch it out without a recompile.
There is more to Spring than just IoC also. I'm working on the data access layer, Aleks has done wonders with support for ASP.NET and Web Services including master pages functionality for ASP.NET 1.1. Microsoft won't be shipping this until 2.0 close to the end of the year.
There is also Transaction management and AOP support. Grab the latest code from CVS to check out all these features. Many of them are very stable. They just aren't included in the 0.6 RC's b/c this release is mainly an IoC release.
Aleks Seovic
04-10-2005, 11:22 AM
Hi Jon,
I guess the shortest answer I could give to "What are you using Spring.Net for?" is "anything that I find it useful for", and that's a lot ;)
I'm not sure I'd say that Spring Dependency Injection is the same as Abstract Factory, I believe it gives you a lot more. If you use Spring in a factory-like fashion (and unfortunately, I believe that all of the examples that ship with 0.6RCx releases use it exactly like that), than it really isn't much more that that, because you are not using full power of DI throughout your application -- you are still using it to wire objects within the container, but your code relies on calls to GetObject method to get instances it needs.
Ideally, you should not have a single GetObject call in your application -- everything should be wired for you by the container, so you can manage all object relationships externally, in a config file. If you look at Spring.Web examples on the wiki, that's exactly what we allow you to do for web applications, and that is the level of support that we will eventually provide for other application types as well -- console, Windows and Windows Services apps.
Second, Spring provides a very generic and flexible mechanism for configuration of your objects, so you don't have to write custom configuration code in your apps. For example, if yoor app needs to know URL of the mail server to use to send emails, you can easily configure that within your mail service object definition, either directly or better yet using property placeholder. All you need to do to allow your service to use this value is define a property for it within your service class.
You also mention that you can use Spring to inject "service location". If that means that you use Spring to inject service name, and then use some kind of service locator to actually find the service to use, I disagree -- you should use Spring to inject service itself, not its name/location.
Service locator and Spring DI container accomplish the same thing, but in a fundamentally different way. With service locator, your client is still responsible for looking up its collaborators and it needs to have a reference to a service locator as well (although, more often than not service locator is implemented as a singleton, which makes it easy to find but difficult to test). On the other hand, Spring will simply inject collaborator for you, there is nothing client needs to do. To illustrate this, let's look at the sample written using service locator first and then refactor it to use Spring DI. For the sake of discussion, let's say that example is code behind class from ASP.Net application that uses UserManager service to create new user, but same principle applies to other classes that need to look up their collaborators as well:
public class UserRegistrationForm : Page
{
private User user; // data model
public void CreateUser(object sender, EventArgs args)
{
IUserManager userManager = ServiceLocator.Instance.GetService("userManager") as IUserManager;
userManager.CreateUser(user);
}
}
The main issue with this code is that it has hardcoded dependency to a service locator. In this case, if you wanted to unit test UserRegistrationForm in isolation, it would be difficult to provide mock implementation of IUserManager without changing either the code or configuration of the service locator itself.
Of course, you could inject service locator using Spring, and you can actually use Spring ApplicationContext/ObjectFactory as a service locator, but why not simply inject necessary collaborators directly and make UserRegistrationForm completely unaware of the environment it's running in:
public class UserRegistrationForm : Page
{
private User user; // data model
private IUserManager userManager;
public IUserManager UserManager
{
set { userManager = value; }
}
public void CreateUser(object sender, EventArgs args)
{
userManager.CreateUser(user);
}
}
To me, this is much cleaner -- client simply exposes property setters for its collaborators and assumes that they will be properly set before any of the methods that use them are called.
In this case, you would use Spring configuration file to specify which implementation of IUserManager to use, but for testing purposes you wouldn't need Spring at all -- you would simply set mock implementation directly:
[Test]
public void TestCreateUser()
{
UserRegistrationForm form = new UserRegistrationForm();
form.User = new User(...);
form.UserManager = new MockUserManager();
// do the tests against mock user manager
}
Finally, as Jason already mentioned, there is a lot more to Spring than core DI container.
Spring.Web adds support for master pages, localization, data model management, result mapping, bidirectional data binding, just to name the few.
Spring.Aop gives you the ability to define aspects within your application, including both interceptors and introductions.
Spring.Services gives you location transparency for your services by allowing you to export plain .Net objects as enterprise services, web services or remote objects.
Spring.Data raises the abstraction level for ADO.Net data access and will eventually provide integration with popular data access frameworks, such as iBATIS.Net and NHibernate. It will also allow you to handle transactions the same way regardless of the data access framework you use.
We also have plans to add support for Windows apps, etc.
Overall, Spring.Net is a full-blown application framework whose Java counterpart has already been proven as an extremely popular way of building enterprise applications. Core DI container is just one part of it, although very important part that other modules leverage to a great extent.
I'd encourage you to read documentation on the wiki to see what else is there that could help you build applications better and faster. I really believe that if you give Spring a try you will find as an end result that your applications are more flexible, with better defined interfaces between components, and that you will have to do less grunt work and be able to focus more on core business logic and leave most of the plumbing stuff to Spring.
Regards,
Aleks
SecretSquirrel123
04-12-2005, 02:53 AM
Thanks to you both for the reply and all the hard work to port this tool to the .NET work. I am very excited about it. :D
I am going over the docs now, and will come back with some more questions later.
Jon Paugh
Rick Evans
04-12-2005, 08:13 AM
DAOs.
That's it. Sighs... yeah, I know, all these cool features and I'm using Spring.NET... to inject DAO's. Well, it does make the (unit) testing (slightly) easier.
Oh yeah, some connection strings and suchlike are also being injected via PropertyPlaceHolderConfigurer. And a coupla message queue endpoints. Oh, and some custom iBatis.NET IFactoryObjects and IBatisTemplates for the various DAOs.
Oh well, easy come easy go :?
Matthew.V
04-26-2005, 06:33 PM
Ideally, you should not have a single GetObject call in your application -- everything should be wired for you by the container, so you can manage all object relationships externally, in a config file.
Hi Aleks,
Is there a way to have this feature, I mean not having a single call to GetObject, in a non web application.
I'm currently busy developping the business and data access layers of my app and I'm using a kind of business delegate to enter the business layer when coming from the presentation layer (not developped yet - could be done with Spring.Web later).
I've created factories for these delegates, and it's in these factories that I make calls to Spring to get instances of my business delegates...all the rest being wired by Spring as it should be.
So do you think I could be able to do without these calls ?
Matthew
Aleks Seovic
04-27-2005, 05:06 AM
I'm a bit confused because you are saying that presentation layer might be developed with Spring.Web later, while at the same time asking if it can be done in a non-web application.
If you are building a web app using Spring.Web it's easy -- you simply inject your business services into pages. We don't have same level of support for other application types (Windows Forms, Console, Windows Service) yet, but we will be adding it in the future.
For now, your approach is ok, even though not ideal. Once we provide this support for non-web applications you will be able to throw away your factories and inject services directly using configuration.
- Aleks
Matthew.V
04-27-2005, 09:11 AM
Ok, thanks.
I'm a bit confused because you are saying that presentation layer might be developed with Spring.Web later, while at the same time asking if it can be done in a non-web application.
I know it's confusing but to keep it short, I have no idea yet whether the final app will be web oriented or more like a win forms app (or even something headless)...Anyway, for the moment, I'm just developping the business part and all what's behind it (data layer amongst others) , which has to be the same for anything that will be built upon it later.
And if it happens to be a win forms app first, I was wondering how I could do without any GetObject call.
But even being confused, you answered my question, so it's ok :)
vBulletin® v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.