#c# #dependency-injection #castle-windsor
#c# #внедрение зависимостей #castle-windsor
Вопрос:
Я пытаюсь изучить di с использованием windsor и сталкиваюсь с проблемами. У меня есть существующий DAL, который я использую, и я хотел бы использовать di с этим dal. У меня есть следующий интерфейс (упрощенный ради этого поста) —
public interface IConnection
{
void OpenConnection(string ConnectionStringName);
void CloseConnection();
DbDataReader ExecuteReader(string query);
}
и реализация —
public class Connection : IConnection
{
private DBManager manager = new DBManager();
public void OpenConnection(string ConnectionStringName)
{
manager.OpenConnection("connectionstringname");
}
public void CloseConnection()
{
manager.CloseConnection();
}
public DbDataReader ExecuteReader(string query)
{
return manager.ExecuteReader(query, CommandType.Text);
}
}
Вот мой установщик windsor —
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<IConnection>().ImplementedBy<Connection>()
.LifeStyle.Transient
);
}
и вот где я делаю инъекцию —
public class GetData
{
private IConnection conn;
public GetData()
{
}
public GetData(IConnection conn)
{
this.conn = conn;
}
public List<Entity> GetAllData()
{
List<Entity> data= new List<Entity>();
//IConnection conn = new Connection();
conn.OpenConnection("connectionstringname");
try
{
var r = conn.ExecuteReader("select ... from ...");
//code to convert reader to data list
r.Dispose();
}
catch (Exception ex)
{
throw ex;
}
finally
{
conn.CloseConnection();
}
return data;
}
}
внедрение не работает. Если я выполняю пошаговый код, conn всегда равен нулю в GetAllData.
когда я выполняю установку, появляется зависимость IConnection / Connection, и в ней говорится, что все требуемые зависимости могут быть разрешены.
Кто-нибудь может увидеть что-нибудь, что я делаю неправильно? Как я уже сказал, я новичок в di, поэтому, если я использую его неправильно, пожалуйста, дайте мне знать.
Спасибо
РЕДАКТИРОВАТЬ — Я не совсем уверен, что понимаю. Если я изменю свой установщик на следующий, он по-прежнему не будет работать —
container.Register(
Component.For<IConnection>().ImplementedBy<Connection>()
.LifeStyle.Transient
);
container.Register(
Component.For<GetData>()
);
container.Resolve<GetData>();
Я далек от истины по сравнению с тем, что вы сказали, или я двигаюсь в правильном направлении?
Комментарии:
1. где бы мне зарегистрировать getData?
2. Вам нужно зарегистрироваться
GetData
в контейнере, затем разрешить его из контейнера. Если вы просто сделаетеnew GetData()
, контейнер ничего не сможет впрыснуть.3. Маурисио — спасибо за помощь, но я все еще не понимаю. пожалуйста, посмотрите правки выше — двигаюсь ли я в правильном направлении?
4. @czuroski: да, выглядит нормально. Можете ли вы опубликовать полный тестовый пример, чтобы я мог точно определить вашу проблему?
5. @Mauricio — У меня не написано ни одного тестового примера…. Я еще не пытался написать ни одного, поскольку не был уверен, как с ними справиться.
Ответ №1:
Не уверен, и я могу ошибаться, но я не заметил, чтобы вы вызывали
container.Resolve
Если вы работали с ASP.NET MVC, вы можете заставить это работать автоматически с помощью внедрения контроллера, но вам все равно нужно будет подключить интерфейс к какому-то заводскому методу. В вашем примере я бы добавил
public class GetData
{
private IConnection conn = ContainerManager.Instance.Resolve<IConnection>();
//where ContainerManager.Instance points to the container instance
...
}
Комментарии:
1. Я использую MVC, и у меня работает внедрение контроллера. было бы лучше вызвать container.resolve, где вы сказали, или в моем WindsorControllerFactory?
2. @czuroski о, я понимаю. Я не думаю, что вы можете использовать ASP.NET Внедрение MVC для чего угодно, кроме внедрения контроллера , поэтому я думаю (может быть, это неверно), вы не можете использовать это, потому что ASP.NET имеет встроенные фабрики, которые подключаются автоматически за сценой. В своих проектах я создаю базовый класс, который содержит всю
Resolve
логику, и наследую типы из этой базы.
Ответ №2:
вы вызывали install ()? например:
container.Install(Castle.Windsor.Installer.Configuration.FromAppConfig());